package com.quanyan.place.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.quanyan.place.entity.*;
import com.quanyan.place.entity.dto.OrderHistoryDTO;
import com.quanyan.place.entity.dto.OrderItemCostDTO;
import com.quanyan.place.service.*;
import com.quanyan.place.utils.PlaceOrderUtil;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import sms.SmsApi;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.quanyan.api.APIRequest;
import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.AssetsType;
import com.quanyan.assets.entity.TbUserAssets;
import com.quanyan.assets.enums.CouponOrderType;
import com.quanyan.assets.request.ReqCoupon;
import com.quanyan.assets.request.ReqRuleDetail;
import com.quanyan.assets.request.ReqUserInfo;
import com.quanyan.assets.response.RespCoupon;
import com.quanyan.assets.response.RespOrderCoupon;
import com.quanyan.assets.response.RespRuleDetail;
import com.quanyan.assets.service.CouponService;
import com.quanyan.assets.service.UserAssetsService;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.enums.BaseEnum;
import com.quanyan.common.enums.SysParameterConfigEnum;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.http.HttpClientUtils;
import com.quanyan.common.utils.CommonUtils;
import com.quanyan.common.utils.DateTimeUtils;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.common.utils.ServletUtils;
import com.quanyan.common.utils.UUIDUtils;
import com.quanyan.messagepush.entity.Alert;
import com.quanyan.messagepush.entity.Jump;
import com.quanyan.messagepush.entity.Payload;
import com.quanyan.messagepush.entity.PushMessage;
import com.quanyan.messagepush.entity.ReqPushMessage;
import com.quanyan.messagepush.enums.BoxName;
import com.quanyan.messagepush.enums.BoxType;
import com.quanyan.messagepush.enums.IdType;
import com.quanyan.messagepush.enums.MsgType;
import com.quanyan.orderpay.request.ReqOrderCancel;
import com.quanyan.orderpay.request.ReqOrderSave;
import com.quanyan.orderpay.request.ReqPayInfo;
import com.quanyan.orderpay.request.ReqProductDetail;
import com.quanyan.orderpay.response.RespPreOrder;
import com.quanyan.orderpay.service.OrderPayService;
import com.quanyan.pay.enums.OrderStatusEnum;
import com.quanyan.place.biz.IBaseService;
import com.quanyan.place.cache.PlaceRedisTemplate;
import com.quanyan.place.constants.PlaceConstants;
import com.quanyan.place.entity.apireq.ReqOrderOperate;
import com.quanyan.place.entity.apireq.ReqOrderPay;
import com.quanyan.place.entity.apireq.ReqPlaceTicketInfo;
import com.quanyan.place.entity.apireq.ReqQRCode;
import com.quanyan.place.entity.apireq.ReqTicketPayInfo;
import com.quanyan.place.entity.apiresp.AvailableDate;
import com.quanyan.place.entity.apiresp.RespCardInfo;
import com.quanyan.place.entity.apiresp.RespCategory;
import com.quanyan.place.entity.apiresp.RespPayInfo;
import com.quanyan.place.entity.apiresp.RespPlaceTicketInfo;
import com.quanyan.place.entity.apiresp.RespPlaceUserInfo;
import com.quanyan.place.entity.vo.PlaceMemberCardVo;
import com.quanyan.place.entity.vo.PlaceTicketPushOrderVo;
import com.quanyan.place.entity.vo.RespPlaceTicketInfoVo;
import com.quanyan.place.entity.vo.TicketPushOrderVo;
import com.quanyan.place.enums.PlaceErrorCodeEnum;
import com.quanyan.place.mapper.CagetoryMapper;
import com.quanyan.place.mapper.PlaceMapper;
import com.quanyan.place.mapper.PosUnionPayMapper;
import com.quanyan.place.mapper.TbBizPlaceMapper;
import com.quanyan.place.mapper.TbBizPlaceMemberCardMapper;
import com.quanyan.place.mapper.TbBizPlaceMemberCardTypeMapper;
import com.quanyan.place.mapper.TbBizPlaceMemberCardTypeTicketMapper;
import com.quanyan.place.mapper.TbBizPlaceMemberOpHistoryMapper;
import com.quanyan.place.mapper.TbBizPlaceOrderHistoryMapper;
import com.quanyan.place.mapper.TbBizPlaceOrderItemMapper;
import com.quanyan.place.mapper.TbBizPlaceOrderManagerMapper;
import com.quanyan.place.mapper.TbBizPlaceOrderMapper;
import com.quanyan.place.mapper.TbBizPlacePayItemMapper;
import com.quanyan.place.mapper.TbBizPlaceRuleMapper;
import com.quanyan.place.mapper.TbPlaceTicketSalePlanMapper;
import com.quanyan.place.mapper.TbPlaceTicketStatisticsMapper;
import com.quanyan.place.mapper.VPlaceMapper;
import com.quanyan.place.utils.PlaceUtil;
import com.quanyan.place.wrapper.impl.MqPlaceProductWrapperImpl;
import com.quanyan.user.response.RespUserInfoBase;
import com.quanyan.user.response.RespUserInfoDetail;
import com.quanyan.user.serviceFacade.UserServiceFacade;

/**
 * Created by zhaohui on 2016/10/12.
 */
@Service("apiPlaceTicketService")
public class ApiPlaceTicketServiceImpl implements ApiPlaceTicketService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    TbPlaceTicketSalePlanMapper tbPlaceTicketSalePlanMapper;

    @Autowired
    TbPlaceTicketStatisticsMapper tbPlaceTicketStatisticsMapper;

    @Autowired
    private TbBizPlaceMemberCardMapper tbBizPlaceMemberCardMapper;

    @Autowired
    private TbBizPlaceMemberOpHistoryMapper tbBizPlaceMemberOpHistoryMapper;

    @Autowired
    TbBizPlaceOrderMapper tbBizPlaceOrderMapper;

    @Autowired
    TbBizPlaceOrderItemMapper tbBizPlaceOrderItemMapper;

    @Autowired
    TbBizPlacePayItemMapper tbBizPlacePayItemMapper;
    @Autowired
    IBaseService ibaseService;

    @Autowired
    BaseService baseService;

    @Autowired
    TbBizPlaceMapper tbBizPlaceMapper;

    @Autowired
    OrderPayService orderPayService;

    @Autowired
    PlaceMemberService placeMemberService;

    @Autowired
    TbBizPlaceOrderManagerMapper tbBizPlaceOrderManagerMapper;
    @Autowired
    UserAssetsService userAssetsService;
    @Autowired
    private CouponService couponService;

    @Autowired
    private TbBizPlaceMemberCardTypeTicketMapper tbBizPlaceMemberCardTypeTicketMapper;

    @Autowired
    TbBizPlaceRuleMapper tbBizPlaceRuleMapper;

    @Autowired
    VPlaceMapper vPlaceMapper;

    @Value("${notify.url.payUrl}")
    private String payUrl;

    @Value("${notify.url.refundUrl}")
    private String refundUrl;

    @Value("${notify.url.exception.refundUrl}")
    private String exceptionRefundUrl;

    @Value("${notify.url.closeOrderUrl}")
    private String closeOrderUrl;
    @Autowired
    private TbBizPlaceMemberCardTypeMapper tbBizPlaceMemberCardTypeMapper;

    @Autowired
    TbBizPlaceOrderHistoryMapper tbBizPlaceOrderHistoryMapper;
    @Autowired
    PlaceMapper placeMapper;

    @Value("${c.service.url}")
    public String cAddress;

    @Autowired
    MqPlaceProductWrapperImpl mqPlaceProductWrapper;

    @Autowired
    UserServiceFacade userServiceFacade;

    @Autowired
    PlaceBaseService placeBaseService;

    @Autowired
    PlaceMessageService placeMessageService;

    @Autowired
    private PlaceTicketService placeTicketService;

    @Autowired
    com.quanyan.place.biz.SmsService  placeSmsService;
    
    @Autowired
    PosUnionPayMapper posUnionPayMapper;

    @Autowired
    CagetoryMapper cagetoryMapper;

    @Autowired
    PlaceRedisTemplate placeRedisTemplate;
    @Value("${weixin.appid}")
    private String appid;
    @Value("${weixin.secret}")
    private String secret;


    @Autowired
    ApiPlaceOrderService apiPlaceOrderService;

    /**
     * 获取门票计划
     *
     * @param placeId
     * @param chooseDate
     * @param categoryId
     * @return
     */
    private List<TbPlaceTicketSalePlan> getTbPlaceTicketSalePlan(Integer placeId, Long chooseDate, Integer categoryId,Integer salePlanId) {
        TbPlaceTicketSalePlanExample tbPlaceTicketSalePlanExample = new TbPlaceTicketSalePlanExample();
        TbPlaceTicketSalePlanExample.Criteria criteria = tbPlaceTicketSalePlanExample.createCriteria();
        if (placeId != null) {
            criteria.andPlaceIdEqualTo(placeId);
        }
        if (chooseDate != null) {
            String date = DateTimeUtils.format(chooseDate);
            Integer week = DateUtils.getDayOfWeek(DateUtils.strToDate(date));
            criteria.andStartWeekLessThanOrEqualTo((byte) week.intValue());
            criteria.andEndWeekGreaterThanOrEqualTo((byte) week.intValue());
        }
        if (categoryId != null) {
            criteria.andCategoryIdEqualTo(categoryId);
        }
        if (null != salePlanId){
            criteria.andIdEqualTo(salePlanId);
        }
        criteria.andStatusEqualTo((byte) 1);//TODO
        criteria.andIsEffectiveEqualTo((byte) 1);//TODO
        List<TbPlaceTicketSalePlan> lists = tbPlaceTicketSalePlanMapper.selectByExample(tbPlaceTicketSalePlanExample);
        List<TbPlaceTicketSalePlan> newLists = new ArrayList<>();


        for (TbPlaceTicketSalePlan list : lists) {
            Date endTime = list.getEndTime();
            String tempTime =DateTimeUtils.formatLongToStr(chooseDate)+" "+DateTimeUtils.timeToStr(endTime)+":00";
            if (PlaceUtil.compareTime(tempTime)){
                newLists.add(list);
            }

        }
        return newLists;
    }

    private TbPlaceTicketSalePlan getTicketSalePlace(Integer id){
       return tbPlaceTicketSalePlanMapper.selectByPrimaryKey(id);
    }

    /**
     * 获取优惠券门票时间段
     * @param ticketSalePlans
     * @param chooseDate
     * @return
     */
    private List<String> ticketLists(List<TbPlaceTicketSalePlan> ticketSalePlans,Long chooseDate){
        List<String> placeDateTimeList = new ArrayList<>();
        for (TbPlaceTicketSalePlan ticketSalePlan : ticketSalePlans) {
            placeDateTimeList.add(DateTimeUtils.formatLongToStr(chooseDate) + " " +DateTimeUtils.timeToStr(ticketSalePlan.getStartTime())+","+
                    DateTimeUtils.formatLongToStr(chooseDate) + " " +DateTimeUtils.timeToStr(ticketSalePlan.getEndTime()));
        }
        return placeDateTimeList;
    }
    /**
     * 封装门票返回对象
     * @param lists
     * @param reqPlaceTicketInfo
     * @return
     */
    private List<RespPlaceTicketInfoVo> placeTicketInfo(List<TbPlaceTicketSalePlan> lists,ReqPlaceTicketInfo reqPlaceTicketInfo){
        List<RespPlaceTicketInfoVo> placeTicketInfo = new ArrayList<>();
        if (!org.springframework.util.CollectionUtils.isEmpty(lists)){
            for (TbPlaceTicketSalePlan tbPlaceTicketSalePlan : lists) {
                RespPlaceTicketInfoVo placeTicketInfoVo = new RespPlaceTicketInfoVo();
                String endTime = DateTimeUtils.timeToStr(tbPlaceTicketSalePlan.getEndTime());
                placeTicketInfoVo.setEndDate(endTime);//结束时段
                endTime =DateTimeUtils.formatLongToStr(reqPlaceTicketInfo.getChooseDate())+" "+endTime+":00";
                if (!PlaceUtil.compareTime(endTime)){
                    continue;
                }
                
               
              
                placeTicketInfoVo.setPrice(tbPlaceTicketSalePlan.getPrice());//价格
                
                placeTicketInfoVo.setStartDate(DateTimeUtils.timeToStr(tbPlaceTicketSalePlan.getStartTime()));//开始时段

                placeTicketInfoVo.setTicketTimeOut(PlaceUtil.compareTime(endTime));
                placeTicketInfoVo.setTicketName(tbPlaceTicketSalePlan.getTicketName());
                placeTicketInfoVo.setCategoryId(tbPlaceTicketSalePlan.getCategoryId());
                placeTicketInfoVo.setSalePlanId(tbPlaceTicketSalePlan.getId());
                placeTicketInfoVo.setMemberPrice(tbPlaceTicketSalePlan.getMemberPrice());
                placeTicketInfoVo.setStartWeek(tbPlaceTicketSalePlan.getStartWeek());
                placeTicketInfoVo.setEndWeek(tbPlaceTicketSalePlan.getEndWeek());
                //获取阀值
                TbPlaceTicketStatistics ticketStatistics =
                        getTicketStatistics(tbPlaceTicketSalePlan.getId(), reqPlaceTicketInfo.getPlaceId(), new Date(reqPlaceTicketInfo.getChooseDate()), null);
                if (null == ticketStatistics){
                    placeTicketInfoVo.setLimitStatus(0);
                }else{
                    //卖出去的票数
                    Integer total = ticketStatistics.getTotal();
                    if (total != null) {
                        Integer limitNum = tbPlaceTicketSalePlan.getLimitNum();
                        if (total > limitNum) {
                            placeTicketInfoVo.setLimitStatus(1);//TODO 爆满
                        } else {
                            placeTicketInfoVo.setLimitStatus(0);
                        }
                    }
                }
                placeTicketInfo.add(placeTicketInfoVo);
            }

            Comparator<RespPlaceTicketInfoVo> comparator = new Comparator<RespPlaceTicketInfoVo>() {
                @Override
                public int compare(RespPlaceTicketInfoVo o1, RespPlaceTicketInfoVo o2) {
                    return o1.getStartDate().compareTo(o2.getStartDate()) == 0 ?
                            o1.getStartDate().compareTo(o2.getStartDate()) :
                            o1.getStartDate().compareTo(o2.getStartDate());
                }
            };
            Collections.sort(placeTicketInfo, comparator);

        }

        return placeTicketInfo;
    }

    /**
     * 购买门票
     * @param reqPlaceTicketInfo
     * @return
     */
    @Override
    public APIResponse<RespPlaceTicketInfo> placeTicketInfo(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer uid = (Integer) httpServletRequest.getAttribute("uid");
        RespPlaceTicketInfo respPlaceTicketInfo = new RespPlaceTicketInfo();
        Integer placeId = reqPlaceTicketInfo.getPlaceId();
        Long chooseDate = reqPlaceTicketInfo.getChooseDate();
        Integer categoryId = reqPlaceTicketInfo.getCategoryId();
        //判断从今天起7天之内的是否有可用门票，
        List<AvailableDate> availableDateLists = availableDateList(reqPlaceTicketInfo);
        respPlaceTicketInfo.setAvailableDateList(availableDateLists);

        /**扫码门票 **/
        Integer salePlanId = reqPlaceTicketInfo.getSalePlanId();
        List<TbPlaceTicketSalePlan> lists = null;
        if (null != salePlanId){
             lists = getTbPlaceTicketSalePlan(placeId, chooseDate, categoryId,salePlanId);
        }else{
             lists = getTbPlaceTicketSalePlan(placeId, chooseDate, categoryId,null);
        }


        if (!org.springframework.util.CollectionUtils.isEmpty(lists)){
            List<RespPlaceTicketInfoVo> respPlaceTicketList = placeTicketInfo(lists, reqPlaceTicketInfo);
            respPlaceTicketInfo.setPlaceTicketInfo(respPlaceTicketList);
        }else{
            //第一次请求
            if (null != reqPlaceTicketInfo.getIsUseFirst() ){
                if (reqPlaceTicketInfo.getIsUseFirst().equals(1)){
                    boolean result = false;
                    //选择那一天有门票，如果有true 否则false
                    for (AvailableDate availableDateList : availableDateLists) {
                        if (availableDateList.getIsSaleOut().equals(1)){
                            reqPlaceTicketInfo.setChooseDate(DateTimeUtils.strToDate(availableDateList.getDate()).getTime());
                            respPlaceTicketInfo.setIsUseDate(DateTimeUtils.strToDate(availableDateList.getDate()).getTime());
                            result = true;
                            break;
                        }
                    }
                    if (result){
                        lists = getTbPlaceTicketSalePlan(placeId, reqPlaceTicketInfo.getChooseDate(), reqPlaceTicketInfo.getCategoryId(),null);
                        if (!org.springframework.util.CollectionUtils.isEmpty(lists)){
                            List<RespPlaceTicketInfoVo> respPlaceTicketList = placeTicketInfo(lists, reqPlaceTicketInfo);
                            respPlaceTicketInfo.setPlaceTicketInfo(respPlaceTicketList);
                        }
                    }else{
                        //如果没有默认类型的门票，则取出category元素中第一个类型
                        List<RespCategory> ticketCategory = getPlaceTicketSalePlanCategoryId(reqPlaceTicketInfo);
                        for (RespCategory respCategory : ticketCategory) {
                            reqPlaceTicketInfo.setCategoryId(respCategory.getId());
                            break;
                        }
                        //查询取出category类型7天中是否有可售门票
                        availableDateLists = availableDateList(reqPlaceTicketInfo);
                        respPlaceTicketInfo.setAvailableDateList(availableDateLists);
                        for (AvailableDate availableDateList : availableDateLists) {
                            if (availableDateList.getIsSaleOut().equals(1)){
                                reqPlaceTicketInfo.setChooseDate(DateTimeUtils.strToDate(availableDateList.getDate()).getTime());
                                respPlaceTicketInfo.setIsUseDate(DateTimeUtils.strToDate(availableDateList.getDate()).getTime());
                                result = true;
                                break;
                            }
                        }
                        if (result){
                            lists = getTbPlaceTicketSalePlan(placeId, reqPlaceTicketInfo.getChooseDate(), reqPlaceTicketInfo.getCategoryId(),null);
                            if (!org.springframework.util.CollectionUtils.isEmpty(lists)){
                                List<RespPlaceTicketInfoVo> respPlaceTicketList = placeTicketInfo(lists, reqPlaceTicketInfo);
                                respPlaceTicketInfo.setPlaceTicketInfo(respPlaceTicketList);
                            }
                        }else {
                            List<RespPlaceTicketInfoVo> respPlaceTicketList =new ArrayList();
                            respPlaceTicketInfo.setPlaceTicketInfo(respPlaceTicketList);
                        }
                    }
                }
            }else{
                List<RespPlaceTicketInfoVo> respPlaceTicketList =new ArrayList();
                respPlaceTicketInfo.setPlaceTicketInfo(respPlaceTicketList);
            }
        }

        //respPlaceTicketInfo.setSourceType(1);
        respPlaceTicketInfo.setServerTime(System.currentTimeMillis());
        respPlaceTicketInfo.setPayTypeInfo(getPayInfo());
        respPlaceTicketInfo.setRespCardInfos(getRespCardInfo(uid, placeId, reqPlaceTicketInfo.getCategoryId(), null));
        respPlaceTicketInfo.setCategorys(getPlaceTicketSalePlanCategoryId(reqPlaceTicketInfo));
        respPlaceTicketInfo.setCategoryInfo(getPlaceTicketSalePlanCategoryIdMap(reqPlaceTicketInfo));
        TbBizPlace tbBizPlace = tbBizPlaceMapper.selectByPrimaryKey(placeId);// TODO 可以从缓存中获取
        respPlaceTicketInfo.setCityId(tbBizPlace.getCityId());
        respPlaceTicketInfo.setPlaceName(tbBizPlace.getName());

        //场馆自营才返回鸟蛋和优惠券信息
        if (tbBizPlace.getBusinessMode() != null && PlaceConstants.BUSINESS_MODE_SELF_SUPPORT.equals(tbBizPlace.getBusinessMode())) {
            respPlaceTicketInfo.setGetAccumulateRule(getAccumulateRule(uid));
            respPlaceTicketInfo.setRespOrderCoupon(respOrderCoupon(uid, categoryId, new BigDecimal(0),
                    tbBizPlace.getCityId(),lists,chooseDate));
        }

        return APIResponse.returnSuccess(respPlaceTicketInfo);
    }

    /**
     * 门票连续时间区间
     * @return
     */
    private List<AvailableDate> availableDateList(ReqPlaceTicketInfo reqPlaceTicketInfo){
        List<AvailableDate> availableDateList = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            AvailableDate availableDate = new AvailableDate();
            long auctionTime = 0;
            long temp = i * 86400000L + auctionTime;
            long time = System.currentTimeMillis() + temp;
            String date = DateUtils.transferLongToDateString(time);
            List<TbPlaceTicketSalePlan> lists = getTbPlaceTicketSalePlan(reqPlaceTicketInfo.getPlaceId(), time, reqPlaceTicketInfo.getCategoryId(),null);
            if (lists != null && lists.size()>0){
                availableDate.setIsSaleOut(1);
            }else{
                availableDate.setIsSaleOut(0);
            }
            availableDate.setDate(date);
            availableDate.setWeek(DateUtils.dayForWeek(date));
            availableDateList.add(availableDate);
        }
        return availableDateList;
    }
    /**
     * 根据场馆id查询场馆所销售的门票
     * @param reqPlaceTicketInfo
     * @return
     */
    private List<RespCategory>  getPlaceTicketSalePlanCategoryId(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        TbPlaceTicketSalePlanExample tbPlaceTicketSalePlanExample = new TbPlaceTicketSalePlanExample();
        TbPlaceTicketSalePlanExample.Criteria criteria = tbPlaceTicketSalePlanExample.createCriteria();
        criteria.andPlaceIdEqualTo(reqPlaceTicketInfo.getPlaceId());
        criteria.andStatusEqualTo((byte) 1);//TODO
        criteria.andIsEffectiveEqualTo((byte) 1);//TODO
        List<TbPlaceTicketSalePlan> lists = tbPlaceTicketSalePlanMapper.selectByExample(tbPlaceTicketSalePlanExample);
        List<RespCategory> categoryList = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(lists)) {
            for (TbPlaceTicketSalePlan list : lists) {
                Integer categoryId = list.getCategoryId();
                RespCategory respCategory = new RespCategory();
                respCategory.setId(categoryId);
                respCategory.setName(ibaseService.getCommonDataCache("cagetory" + categoryId.toString()));
                categoryList.add(respCategory);
            }
        }

        List<RespCategory> listWithoutDup1 = new ArrayList<>(new HashSet<>(categoryList));
        List<RespCategory> respCategoriess = new ArrayList<>();

        for (RespCategory respCategory : listWithoutDup1) {
            if (respCategory.getId().intValue() == reqPlaceTicketInfo.getCategoryId().intValue()) {
                respCategoriess.add(0, respCategory);
            } else {
                respCategoriess.add(respCategory);
            }
        }

        return respCategoriess;
    }

    private Map<Integer,String>   getPlaceTicketSalePlanCategoryIdMap(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        TbPlaceTicketSalePlanExample tbPlaceTicketSalePlanExample = new TbPlaceTicketSalePlanExample();
        TbPlaceTicketSalePlanExample.Criteria criteria = tbPlaceTicketSalePlanExample.createCriteria();
        criteria.andPlaceIdEqualTo(reqPlaceTicketInfo.getPlaceId());
        criteria.andStatusEqualTo((byte) 1);//TODO
        criteria.andIsEffectiveEqualTo((byte) 1);//TODO
        List<TbPlaceTicketSalePlan> lists = tbPlaceTicketSalePlanMapper.selectByExample(tbPlaceTicketSalePlanExample);
        Map<Integer,String> categoryMap = new HashMap<>();

        if (CollectionUtils.isNotEmpty(lists)) {
            for (TbPlaceTicketSalePlan list : lists) {
                Integer categoryId = list.getCategoryId();
                if (!categoryMap.containsKey(categoryId)){
                    categoryMap.put(categoryId,ibaseService.getCommonDataCache("cagetory" + categoryId.toString()));
                }

            }
        }

        return categoryMap;
    }

    /**
     * 获取支付方式信息
     * @return
     */
    private List<RespPayInfo> getPayInfo() {
        List<RespPayInfo> payInfos = new ArrayList<>();
        RespPayInfo respPayInfo1 = new RespPayInfo();
        respPayInfo1.setPayId(PlaceConstants.PAY_WAY_ALIPAY);
        respPayInfo1.setPayType("支付宝");
        payInfos.add(respPayInfo1);
        RespPayInfo respPayInfo2 = new RespPayInfo();
        respPayInfo2.setPayId(PlaceConstants.PAY_WAY_WEICHAT);
        respPayInfo2.setPayType("微信支付");
        payInfos.add(respPayInfo2);
        RespPayInfo respPayInfo3 = new RespPayInfo();
        respPayInfo3.setPayId(PlaceConstants.PAY_WAY_FOR_CARD);
        respPayInfo3.setPayType("会员卡");
        payInfos.add(respPayInfo3);
       /* RespPayInfo respPayInfo4 = new RespPayInfo();//新增pos银联支付 add by tim
        respPayInfo4.setPayId(PlaceConstants.PLACE_ADMIN_PAY_WAYS_PO_UNIONPAY);
        respPayInfo4.setPayType("pos银行卡(银联)");
        payInfos.add(respPayInfo4);*/
        return payInfos;
    }


    /**
     * 获取用户会员卡信息
     * @param uid
     * @param placeId
     * @param categoryId
     * @return
     */
    @Override
    public List<TbBizPlaceMemberCard> getPlaceMemberInfo(Integer uid, Integer placeId, Integer categoryId, String cardNo) {
        TbBizPlaceMemberCardExample tbBizPlaceMemberCardExample = new TbBizPlaceMemberCardExample();
        TbBizPlaceMemberCardExample.Criteria tbBizPlaceMemberCardCriteria = tbBizPlaceMemberCardExample.createCriteria();
        if (null != uid){
            tbBizPlaceMemberCardCriteria.andMemberUidEqualTo(uid);
        }

        List<Integer> placeIdList = new ArrayList<Integer>();
        if (placeMemberService.checkIsShareVip(placeId)){
            placeIdList = placeMemberService.getShareVipPlaceIds(placeId);
        }
        if (placeIdList.size() > 1){
            tbBizPlaceMemberCardCriteria.andPlaceIdIn(placeIdList);
        } else {
            tbBizPlaceMemberCardCriteria.andPlaceIdEqualTo(placeId);
        }
        if (!StringUtils.isEmpty(cardNo)) {
            tbBizPlaceMemberCardCriteria.andInnerCardNoEqualTo(cardNo);
        }
        tbBizPlaceMemberCardCriteria.andDeadLineTimeGreaterThanOrEqualTo(new Date());//判断截止日期
        tbBizPlaceMemberCardCriteria.andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        tbBizPlaceMemberCardCriteria.andCategoryIdsLike("%" + categoryId + "%");//运动类型
        tbBizPlaceMemberCardCriteria.andStatusEqualTo(PlaceConstants.PLACE_MEMBER_CARD_STATUS_NORMAL);//卡状态
        //tbBizPlaceMemberCardCriteria.andCardTypeEqualTo(PlaceConstants.PLACE_MEMBER_CARD_TYPE_NUMBER);//TODO次卡
        //tbBizPlaceMemberCardCriteria.andSourceTypeEqualTo(PlaceConstants.PLACE_MEMBER);//普通会员
        tbBizPlaceMemberCardExample.setOrderByClause(" id for update");
        List<TbBizPlaceMemberCard> tbBizPlaceMemberCardList = tbBizPlaceMemberCardMapper.selectByExample(tbBizPlaceMemberCardExample);

        if (CollectionUtils.isNotEmpty(tbBizPlaceMemberCardList)){
            Comparator<TbBizPlaceMemberCard> comparator = new Comparator<TbBizPlaceMemberCard>() {
                @Override
                public int compare(TbBizPlaceMemberCard o1, TbBizPlaceMemberCard o2) {
                    return o1.getCardType().compareTo(o2.getCardType())> 0 ?  o2.getCardType().compareTo(o1.getCardType()): o2.getCardType().compareTo(o1.getCardType());
                }
            };
            Collections.sort(tbBizPlaceMemberCardList, comparator);
        }
        return tbBizPlaceMemberCardList;
    }

    /**
     * 封装相应会员卡信息
     *
     * @param uid
     * @param placeId
     * @param categoryId
     * @return
     */
    private List<RespCardInfo> getRespCardInfo(Integer uid, Integer placeId, Integer categoryId, String cardNo) {
        List<RespCardInfo> cardInfos = new ArrayList<>();
        //获取会员卡列表
        List<TbBizPlaceMemberCard> tbBizPlaceMemberCardList = getPlaceMemberInfo(uid, placeId, categoryId, cardNo);
        if (CollectionUtils.isNotEmpty(tbBizPlaceMemberCardList)) {
            for (TbBizPlaceMemberCard tbBizPlaceMemberCard : tbBizPlaceMemberCardList) {
                RespCardInfo respCardInfo = new RespCardInfo();
                BeanUtils.copyProperties(tbBizPlaceMemberCard, respCardInfo);
                //增加会员卡类型
                TbBizPlaceMemberCardType tbBizPlaceMemberCardType = this.tbBizPlaceMemberCardTypeMapper.selectByPrimaryKey(tbBizPlaceMemberCard.getCardTypeId());
                if (!org.springframework.util.StringUtils.isEmpty(tbBizPlaceMemberCardType)){
                    tbBizPlaceMemberCardType.setDescription(null);
                    respCardInfo.setTbBizPlaceMemberCardType(tbBizPlaceMemberCardType);
                }
                //respCardInfo.setAvailableStartTime(DateTimeUtils.timeToStr(tbBizPlaceMemberCard.getAvailableStartTime()));
                //respCardInfo.setAvailableEndTime(DateTimeUtils.timeToStr(tbBizPlaceMemberCard.getAvailableEndTime()));
                respCardInfo.setBalance(tbBizPlaceMemberCard.getSurplusAmount().add(tbBizPlaceMemberCard.getSurplusGiveAmount()));
                respCardInfo.setState(tbBizPlaceMemberCard.getStatus());
                respCardInfo.setSourceType(tbBizPlaceMemberCard.getSourceType());
                respCardInfo.setIsOldMember(tbBizPlaceMemberCard.getIsOldMember());
                // 会员卡与门票是否绑定
                TbBizPlaceMemberCardTypeTicket typeTicket = tbBizPlaceMemberCardTypeTicket(tbBizPlaceMemberCard.getCardTypeId(), null);
                if (typeTicket != null) {
                    respCardInfo.setTicketId(typeTicket.getTicketId());
                    TbPlaceTicketSalePlan tbPlaceTicketSalePlan = tbPlaceTicketSalePlanMapper.selectByPrimaryKey(typeTicket.getTicketId());
                    respCardInfo.setStartWeek(tbPlaceTicketSalePlan.getStartWeek());
                    respCardInfo.setEndWeek(tbPlaceTicketSalePlan.getEndWeek());
                    respCardInfo.setAvailableStartTime(DateTimeUtils.timeToStr(tbPlaceTicketSalePlan.getStartTime()));
                    respCardInfo.setAvailableEndTime(DateTimeUtils.timeToStr(tbPlaceTicketSalePlan.getEndTime()));
                }
                cardInfos.add(respCardInfo);
            }
        }
        return cardInfos;
    }

    /**
     * 会员卡与门票是否绑定
     *
     * @param cardTypeId
     * @param ticketId
     * @return
     */
    private TbBizPlaceMemberCardTypeTicket tbBizPlaceMemberCardTypeTicket(Integer cardTypeId, Integer ticketId) {
        TbBizPlaceMemberCardTypeTicketExample typeTicketExample = new TbBizPlaceMemberCardTypeTicketExample();
        TbBizPlaceMemberCardTypeTicketExample.Criteria criteria = typeTicketExample.createCriteria();
        if (cardTypeId != null) {
            criteria.andCardTypeIdEqualTo(cardTypeId);
        }
        if (ticketId != null) {
            criteria.andTicketIdEqualTo(ticketId);
        }
        List<TbBizPlaceMemberCardTypeTicket> list = tbBizPlaceMemberCardTypeTicketMapper.selectByExample(typeTicketExample);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }


    /**
     * 查询门票统计记录
     *
     * @param ticketId
     * @param placeId
     * @param saleDate
     * @return
     */
    private TbPlaceTicketStatistics getTicketStatistics(Integer ticketId, Integer placeId, Date saleDate, BigDecimal price) {
        TbPlaceTicketStatisticsExample tbPlaceTicketStatisticsExample = new TbPlaceTicketStatisticsExample();
        TbPlaceTicketStatisticsExample.Criteria criteria = tbPlaceTicketStatisticsExample.createCriteria();
        criteria.andPlaceIdEqualTo(placeId);
        criteria.andTicketIdEqualTo(ticketId);
        criteria.andSaleDateEqualTo(saleDate);
        if (price != null) {
            criteria.andSalePriceEqualTo(price);
        }
        tbPlaceTicketStatisticsExample.setOrderByClause(" id for update");
        List<TbPlaceTicketStatistics> list = tbPlaceTicketStatisticsMapper.selectByExample(tbPlaceTicketStatisticsExample);
        TbPlaceTicketStatistics tbPlaceTicketStatistics = null;
        if (list != null && list.size() > 0) {
            tbPlaceTicketStatistics = list.get(0);
        }
        return tbPlaceTicketStatistics;
    }

    /**
     * 更新及添加门票统计记录
     * @param ticketId
     * @param placeId
     * @param chooseDate
     * @param price
     * @param count
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private Integer ticketStatistics(Integer ticketId, Integer placeId, Long chooseDate, BigDecimal price, Integer count) {
        TbPlaceTicketStatistics ticketStatis = getTicketStatistics(ticketId, placeId, new Date(chooseDate), price);
        if (ticketStatis != null) {
            //更新门票数
            ticketStatis.setTotal(ticketStatis.getTotal() + count);//累计门票张数
            int flag = tbPlaceTicketStatisticsMapper.updateByPrimaryKeySelective(ticketStatis);
            if (flag == 1) {
                logger.debug("========================更新门票统计成功。");
            } else {
                logger.debug("========================更新门票统计失败。");
            }
            return flag;
        } else {
            //添加
            TbPlaceTicketStatistics tbPlaceTicketStatistics = new TbPlaceTicketStatistics();
            tbPlaceTicketStatistics.setTicketId(ticketId);
            tbPlaceTicketStatistics.setPlaceId(placeId);
            tbPlaceTicketStatistics.setTotal(count);
            tbPlaceTicketStatistics.setSalePrice(price);
            tbPlaceTicketStatistics.setSaleDate(new Date(chooseDate));
            tbPlaceTicketStatistics.setUpdateTime(new Date());
            tbPlaceTicketStatistics.setCreateTime(new Date());
            int flag = tbPlaceTicketStatisticsMapper.insert(tbPlaceTicketStatistics);
            if (flag == 1) {
                logger.debug("========================添加门票统计成功。");
            } else {
                logger.debug("========================添加门票统计失败。");
            }
            return flag;
        }

    }

    /**
     * 会员卡支付
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    @Override
    public APIResponse<RespPreOrder> cardPay(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer uid = (Integer) httpServletRequest.getAttribute("uid");
        String ver = httpServletRequest.getHeader("APPVersion");
        reqPlaceTicketInfo.setAPPVersion(ver);
        reqPlaceTicketInfo.setUid(uid);
        Integer placeId = reqPlaceTicketInfo.getPlaceId();
        Integer categoryId = reqPlaceTicketInfo.getCategoryId();
        String cardNo = reqPlaceTicketInfo.getCardNo();
        //下单验证
        APIResponse apiResponse = orderVerification(reqPlaceTicketInfo);
        if( apiResponse != null && !apiResponse.isRet()){
            return apiResponse;
        }

        List<TbBizPlaceMemberCard> memberCardList = getPlaceMemberInfo(uid, placeId, categoryId, cardNo);

        if (org.springframework.util.CollectionUtils.isEmpty(memberCardList)) {
            return APIResponse.returnFail("没有会员信息");
        }
        TbBizPlaceMemberCard tbBizPlaceMemberCard = memberCardList.get(0);
        PlaceMemberCardVo placeMemberCard = new PlaceMemberCardVo();
        BeanUtils.copyProperties(tbBizPlaceMemberCard, placeMemberCard);
        reqPlaceTicketInfo.setPlaceMemberCardVo(placeMemberCard);
        Byte cardType = tbBizPlaceMemberCard.getCardType();//卡类型 1 储值卡 2 折扣卡 3储值折扣卡 4 次卡
        reqPlaceTicketInfo.setCardType(cardType);
        if (null == reqPlaceTicketInfo.getChooseDate()){
            return APIResponse.returnFail("时间段不能为空");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String tempChooseDate = sdf.format(reqPlaceTicketInfo.getChooseDate());
        try {
            Integer flag = checkTicketDate(reqPlaceTicketInfo);
            if (sdf.parse(tempChooseDate).getTime() == sdf.parse(sdf.format(new Date())).getTime()){
                if (flag.equals(1)){
                    return APIResponse.returnFail("购买的门票时间段不匹配！");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        Iterator<ReqPayInfo> it = reqPlaceTicketInfo.getPayInfos().iterator();
        while (it.hasNext()) {
            ReqPayInfo payInfo = it.next();
            if (PlaceConstants.PAY_WAY_FOR_COUPON.equals(payInfo.getPayId())) {
                /**为兼容老版本，普通支付及优惠券折扣，当优惠券金额为0，提示升级最新版本**/
                BigDecimal amount = payInfo.getAmount();
                if (null != amount) {
                    int r = amount.compareTo(BigDecimal.ZERO);
                    if (r == 0) {
                        return APIResponse.returnFail(PlaceErrorCodeEnum.COUPON_DISCOUNT_PAY_ERROR);
                    }

                    /**优惠券支付添加 时间段**/
                    List<TbPlaceTicketSalePlan> lists = getTbPlaceTicketSalePlan(placeId, reqPlaceTicketInfo.getChooseDate(), categoryId,null);
                    if (null != lists && lists.size()>0){
                        payInfo.setPlaceDateTimeList(ticketLists(lists, reqPlaceTicketInfo.getChooseDate()));
                    }

                }
            }
        }


        if (PlaceConstants.PLACE_MEMBER_CARD_TYPE_NUMBER.equals(cardType)) {
            //次卡支付
            RespPreOrder respPreOrder = ciCardPreOrder(reqPlaceTicketInfo).getData();
            return APIResponse.returnSuccess(respPreOrder);
        } else if (PlaceConstants.PLACE_MEMBER_CARD_TYPE_VALUE.equals(cardType)) {
            //储值卡支付
            RespPreOrder respPreOrder = prePayCardOrder(reqPlaceTicketInfo).getData();
            return APIResponse.returnSuccess(respPreOrder);
        } else if (PlaceConstants.PLACE_MEMBER_CARD_TYPE_DISCOUNT.equals(cardType)) {
            //折扣卡
            RespPreOrder respPreOrder = disCountCardOrder(reqPlaceTicketInfo).getData();
            return APIResponse.returnSuccess(respPreOrder);
        } else if (PlaceConstants.PLACE_MEMBER_CARD_TYPE_VALUE_DISCOUNT.equals(cardType)) {
            //储值折扣卡
            RespPreOrder respPreOrder = prePayDisCountCardOrder(reqPlaceTicketInfo).getData();
            return APIResponse.returnSuccess(respPreOrder);
        }
         return null;
    }

    /**
     * 会员卡结合优惠券支付
     * @param reqPlaceTicketInfo
     * @param memberCard
     * @param debit
     * @return
     */
    private ReqPlaceTicketInfo payTypeHandle(ReqPlaceTicketInfo reqPlaceTicketInfo,PlaceMemberCardVo memberCard, BigDecimal debit){
        List<ReqPayInfo> payInfos = reqPlaceTicketInfo.getPayInfos();
        for (ReqPayInfo payInfo : payInfos) {
            payInfo.setSportType(reqPlaceTicketInfo.getCategoryId().byteValue());
            if (payInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_COUPON)){
                payInfo.setOrderType(CouponOrderType.PLACE_TICKETS.getId().byteValue());
                /** 会员卡类型： 储值卡 1*/
                if(PlaceConstants.PLACE_MEMBER_CARD_TYPE_VALUE.equals(memberCard.getCardType())){
                    reqPlaceTicketInfo.setDisCountBeforeAmount(debit);//订单价格
                    if (debit.compareTo(payInfo.getAmount()) > 0){
                        debit = debit.subtract(payInfo.getAmount());//订单金额-优惠券金额
                    }else {
                        debit = new BigDecimal(0);
                    }
                    reqPlaceTicketInfo.setDisCountAfterAmount(debit);//用优惠券抵扣后订单金额
                    /** 会员状态： 折扣卡 2*/
                    /** 会员状态： 储值折扣卡*/
                }else if (PlaceConstants.PLACE_MEMBER_CARD_TYPE_DISCOUNT.equals(memberCard.getCardType()) ||
                        PlaceConstants.PLACE_MEMBER_CARD_TYPE_VALUE_DISCOUNT.equals(memberCard.getCardType())){
                    //Double temp = new Double(memberCard.getDiscount()) / 100;
                    //BigDecimal discount = new BigDecimal(temp);
                   // debit = debit.multiply(discount).setScale(2,BigDecimal.ROUND_HALF_UP);
                    reqPlaceTicketInfo.setDisCountBeforeAmount(debit);//订单价格打折以后价格
                    if (debit.compareTo(payInfo.getAmount()) > 0){
                        debit = debit.subtract(payInfo.getAmount());//订单金额-优惠券金额
                    }else {
                        debit = new BigDecimal(0);
                    }
                    //payInfo.setAmount(debit);//优惠券抵扣金额折扣价
                    reqPlaceTicketInfo.setDisCountAfterAmount(debit.setScale(2,BigDecimal.ROUND_HALF_UP));//用优惠券抵扣后订单金额
                }
            }

        }
        return reqPlaceTicketInfo;

    }




    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private APIResponse orderCompleteTicketOperate(ReqPlaceTicketInfo reqPlaceTicketInfo){
        PlaceTicketPushOrderVo placeTicketPushOrderVo = new PlaceTicketPushOrderVo();

        TbBizPlace tbBizPlace = this.tbBizPlaceMapper.selectByPrimaryKey(reqPlaceTicketInfo.getPlaceId());

        /**加入消息推送，提示门票订场成功**/
        PlaceMessage placeMessage = new PlaceMessage();
        placeMessage.setOrderNo(reqPlaceTicketInfo.getOrderNo());
        placeMessage.setOrderType(4);
        List<Integer> uids = new ArrayList<>();
        uids.add(reqPlaceTicketInfo.getUid());
        placeMessage.setUids(uids);
        TbBizPlaceOrderItemExample tbBizPlaceOrderItemExample = new TbBizPlaceOrderItemExample();
        TbBizPlaceOrderItemExample.Criteria placeOrderItem = tbBizPlaceOrderItemExample.createCriteria();
        placeOrderItem.andPlaceOrderIdEqualTo(reqPlaceTicketInfo.getOrderNo());

        List<TbBizPlaceOrderItem> tbBizPlaceOrderItems = tbBizPlaceOrderItemMapper.selectByExample(tbBizPlaceOrderItemExample);
        String salePlanDate =DateUtils.transferDateToString(tbBizPlaceOrderItems.get(0).getConsumeTime());
        String salePlanDateNew = DateUtils.tranferStringToZHCN(salePlanDate);

        if(CollectionUtils.isEmpty(tbBizPlaceOrderItems)){
            APIResponse.returnFail("没有该条订单信息！");
        }else{
            List<TicketPushOrderVo> lists = new ArrayList<>();
            for (TbBizPlaceOrderItem tbBizPlaceOrderItem : tbBizPlaceOrderItems) {
                Integer ticketId = tbBizPlaceOrderItem.getUnitSalePlanId();
                TbPlaceTicketSalePlan placeTicketSalePlan = tbPlaceTicketSalePlanMapper.selectByPrimaryKey(ticketId);
                TicketPushOrderVo ticketPush = new TicketPushOrderVo();
                ticketPush.setTicketName(placeTicketSalePlan.getTicketName());
                ticketPush.setStartTime(placeTicketSalePlan.getStartTime());
                ticketPush.setEndTime(placeTicketSalePlan.getEndTime());
                lists.add(ticketPush);
            }
            placeTicketPushOrderVo.setTicketPushOrderVos(lists);
        }

        placeMessage.setDate(salePlanDateNew);
        placeMessage.setPlaceName(tbBizPlace.getName());
        placeMessage.setPlaceId(reqPlaceTicketInfo.getPlaceId());
        placeMessage.setPayType(PlaceConstants.PAY_WAY_FOR_CARD);
        Cagetory cagetory =cagetoryMapper.selectByPrimaryKey(reqPlaceTicketInfo.getCategoryId());
        placeMessage.setCategoryValue(cagetory.getName());

        boolean result = pushMessageOperate(placeMessage);
        //加入消息队列进行异步消息推送处理，场馆系统自己作为生产者也作为消费者。
        if(!result){
            mqPlaceProductWrapper.pushMessageAsyncSend(placeMessage);
        }
        placeTicketPushOrderVo.setDate(salePlanDateNew);
        placeTicketPushOrderVo.setCategoryId(reqPlaceTicketInfo.getCategoryId());

        ReqOrderOperate orderOperate = new ReqOrderOperate();
        orderOperate.setOperateType(2);
        orderOperate.setOrderNo(reqPlaceTicketInfo.getOrderNo());
        orderOperate.setPlatformType(reqPlaceTicketInfo.getPlatformType());
        orderOperate.setPlaceId(reqPlaceTicketInfo.getPlaceId());
        orderCallBackHistory(orderOperate);
        //发送短信
        ticketSmsSendOperate(placeTicketPushOrderVo, reqPlaceTicketInfo.getUid(), tbBizPlace);
        return APIResponse.returnSuccess("订单支付完成！");
    }


    /**
     * 记录订单回调
     * @param orderOperate
     */
    @Async
    @Override
    public void orderCallBackHistory(ReqOrderOperate orderOperate) {
        OrderHistoryDTO orderHistoryDTO = new OrderHistoryDTO();
        orderHistoryDTO.setReqOrderOperate(orderOperate);
        /**是退款 还是支付成功**/
        orderHistoryDTO.setOrderType(orderOperate.getOperateType());
        apiPlaceOrderService.insertOrderHistory(orderHistoryDTO);
    }
    /**
     * 购买门票成功后消息推送
     * @param placeMessage
     * @return
     */
    private boolean pushMessageOperate(PlaceMessage placeMessage) {
        ReqPushMessage reqPushMessage = new ReqPushMessage();
        PushMessage pushMessage = new PushMessage();
        pushMessage.setTag(BoxName.ORDER.value() + System.currentTimeMillis());
        pushMessage.setTo(placeMessage.getUids());                          //下单用户的uid
        pushMessage.setLogo(Constants.LARK_LOGO);
        pushMessage.setLogoUrl("");
        Payload payload = new Payload();
        String body = "";
        String title = "";
        if(placeMessage.getOrderType() == 4){
            title = "场地门票购买提醒";
            int count = placeTicketService.getTicketSaleCountByOrderNo(placeMessage.getOrderNo());
            body = "您已成功购买" + placeMessage.getDate() + placeMessage.getPlaceName() + "的" +placeMessage.getCategoryValue()+ "门票"+ count +"张。";
        }
        Alert alert = new Alert();
        alert.setTitle("场馆订单");
        pushMessage.setAlert(alert);
        alert.setBody(title);
        payload.setTitle(title);
        payload.setBody(body);
        payload.setBoxType(BoxType.PLACE_ORDER_MSG.value());
        payload.setMsgType(MsgType.JUMP_MSG.value());//预定成功是3 退款是5
        payload.setUrl("/api/place/shops/orderDetail");
        Jump jump = new Jump();
        jump.setIdType(IdType.PLACE_ORDER_DETAIL_PAGE.value());
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("orderNo",placeMessage.getOrderNo());
        jump.setParam(param);
        payload.setJump(jump);

        payload.setTimestamp(System.currentTimeMillis());
        pushMessage.setPayload(payload);
        reqPushMessage.setMsgList(Arrays.asList(pushMessage));

        try {
            String postJson = JSON.toJSONString(reqPushMessage);
            logger.info("---------推送消息：" + postJson);
            String result = HttpClientUtils.postJson(cAddress + "/push/NewMsg.api", postJson);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String errcode = jsonObject.getString("errcode");
            logger.info("---------推送返回：" + result);
            if(errcode != null && errcode.equals("200")){
                return true;
            }
        } catch (Exception e) {
            logger.info("推送消息失败，" + e.getMessage());
        }
        return false;

    }


    /**
     * 购买门票成功后短信推送
     * @param placeTicketPushOrderVo
     * @param uid
     * @param tbBizPlace
     * @return
     */
    @Async
    private boolean ticketSmsSendOperate(PlaceTicketPushOrderVo placeTicketPushOrderVo,Integer uid, TbBizPlace tbBizPlace){
        if(null == placeTicketPushOrderVo){
            return false;
        }
        List<String> mobiles=new ArrayList<>();
        List<String> params=new ArrayList<>();

        String phone="";
        String [] args = new String[3];
        args[0] = "";
        args[1] = "";
        args[2] = "";
        // 联系电话优先取订场咨询电话，订场电话为空时，取客服电话
        TbBizPlaceAttach placeAttach = placeBaseService.getBizPlaceAttach(tbBizPlace.getId());
        if (null != placeAttach && org.apache.commons.lang3.StringUtils.isNotEmpty(placeAttach.getBookingConsultPhone())){
            phone=placeAttach.getBookingConsultPhone();
        } else {
            // 获取系统配置的百灵鸟客服热线
            TbCommonParameter parameterVo = baseService.getParameterByKey(SysParameterConfigEnum.CONFIG_APP_SERVICE_MOBILE.getCode());
            phone=parameterVo!=null?parameterVo.getParameterValue():"";
        }

        String salePlanDateNew = placeTicketPushOrderVo.getDate();
        args[0] = salePlanDateNew + tbBizPlace.getName() + "的" + ibaseService.getCommonDataCache("cagetory" + placeTicketPushOrderVo.getCategoryId().toString());
        List<TicketPushOrderVo> pushOrderVos = placeTicketPushOrderVo.getTicketPushOrderVos();
        if (!org.springframework.util.CollectionUtils.isEmpty(pushOrderVos)){
            for (TicketPushOrderVo TicketPushOrderVo : pushOrderVos) {
                args[1] +=TicketPushOrderVo.getTicketName() + " " + DateTimeUtils.timeToStr(TicketPushOrderVo.getStartTime()) + "-" + DateTimeUtils.timeToStr(TicketPushOrderVo.getEndTime()) + "、";
            }
        }
        args[1] = "[" + args[1].substring(0,args[1].length()-1) + "]";
        args[2] = phone;

        APIResponse<RespUserInfoBase> userMsg = userServiceFacade.queryUserInfo(uid);
        if(!userMsg.isRet()){
            return false;
        }
        RespUserInfoBase respUserInfoBase = userMsg.getData();
        mobiles.add(respUserInfoBase.getMobile());
        params.addAll(Arrays.asList(args));
        try {
           // placeTicketService.asyncSendSms(respUserInfoBase.getMobile(), SmsApi.MESSAGE_TEMPLATE_PLACE_ORDER_TICKET_NOTICE,args,true);
            placeSmsService.sendSms(mobiles,SmsApi.MESSAGE_TEMPLATE_PLACE_ORDER_TICKET_NOTICE, PlaceConstants.PLACE_SMS_TYPE_MESSAGE,params);
        } catch(Exception e){
            logger.info("短信发送失败-------->" + e.getMessage());
            return false;
        }
        //发送短信提醒给场馆人员
        TbBizPlaceNoticeMobile messageVo = placeMessageService.getMobileDataByPlaceId(tbBizPlace.getId());
        APIResponse<RespUserInfoBase>  userInfo=userServiceFacade.queryUserInfo(uid);
        String nickName=userInfo.getData()!=null ? userInfo.getData().getNickName():"";
       if (null != messageVo){
           APIResponse<RespUserInfoBase> resPvo = userServiceFacade.queryUserInfo(uid);
           List<String> mobileList=new ArrayList<>();
           List<String> paramList=new ArrayList<>();
           String[] messageArgs = new String[4];
           //messageArgs[0] = resPvo != null ? resPvo.getData().getMobile() : "";
           messageArgs[0] = nickName;
           messageArgs[1]=args[0];
           messageArgs[2]=args[1];
           messageArgs[3]=resPvo != null ? resPvo.getData().getMobile() : "";

           mobileList.add(messageVo.getMobile());
           paramList.addAll(Arrays.asList(messageArgs));
           try {
               if (!org.springframework.util.StringUtils.isEmpty(messageVo.getMobile())) {
                   //placeTicketService.asyncSendSmsToOperator(messageVo.getMobile(), respUserInfoBase.getMobile(), SmsApi.MESSAGE_TEMPLATE_PLACE_ORDER_REMIND, messageArgs, true);
                   placeSmsService.sendSms(mobileList,SmsApi.MESSAGE_TEMPLATE_PLACE_ORDER_REMIND, PlaceConstants.PLACE_SMS_TYPE_MESSAGE,paramList);
               }
           } catch (java.lang.Exception e) {
               logger.info("短信发送失败-------->" + e.getMessage());
           }
       }
        return true;
    }

    /**
     * 验证门票时间段是否匹配
     * @param reqPlaceTicketInfo
     * @return
     */
    public Integer checkTicketDate(ReqPlaceTicketInfo reqPlaceTicketInfo){
        List<ReqTicketPayInfo> ticketPayInfos = reqPlaceTicketInfo.getTicketPayInfos();
        Integer flag = 0;
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
            Integer ticketId = ticketPayInfo.getSalePlanId();
            TbPlaceTicketSalePlan ticketSalePlan = tbPlaceTicketSalePlanMapper.selectByPrimaryKey(ticketId);
            Date endTime  = ticketSalePlan.getEndTime();
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
            try {
                Date currentTime = sdf.parse(sdf.format(new Date()));
                logger.info("验证门票时间段是否匹配:"+sdf.parse(sdf.format(endTime))+"==="+currentTime);
                if (endTime.compareTo(currentTime) < 0 ){
                   return flag = 1;
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return flag;
    }

    /**
     * 储值卡支付
     *
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private APIResponse<RespPreOrder> prePayCardOrder(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        Integer placeId = reqPlaceTicketInfo.getPlaceId();
        Integer categoryId = reqPlaceTicketInfo.getCategoryId();
        String cardNo = reqPlaceTicketInfo.getCardNo();
        Integer uid = reqPlaceTicketInfo.getUid();
        //获取门票支付信息
        List<ReqTicketPayInfo> ticketPayInfos = reqPlaceTicketInfo.getTicketPayInfos();

        Integer totalCounts = 0;
        //总价格
        BigDecimal totalPrice = new BigDecimal(0);
        BigDecimal debit = new BigDecimal(0);
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
            Integer ticketId = ticketPayInfo.getSalePlanId();
            Integer count = ticketPayInfo.getTicketCount();
            totalCounts += count;
            //客户端传不安全，所以直接从数据库中查询
            TbPlaceTicketSalePlan  placeTicketSalePlan = getTicketSalePlace(ticketId);
            BigDecimal price = placeTicketSalePlan.getMemberPrice();
            //BigDecimal price = ticketPayInfo.getPrice();
            BigDecimal tempPrice = price.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP);
            totalPrice = totalPrice.add(tempPrice);

            BigDecimal ticketDebit = placeTicketSalePlan.getPrice();
            debit = debit.add(ticketDebit.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP));
            logger.info("tiackeId:" + ticketId + "====单价：" + price + "====票数" + count + "====总价" + totalPrice);
            //更新门票销售统计
            ticketStatistics(ticketId, placeId, reqPlaceTicketInfo.getChooseDate(), price, count);
        }
        reqPlaceTicketInfo.setPrimePrice(totalPrice);
        reqPlaceTicketInfo.setDebit(debit);
        TbBizPlace tbBizPlace = tbBizPlaceMapper.selectByPrimaryKey(reqPlaceTicketInfo.getPlaceId());
        reqPlaceTicketInfo.setCityId(tbBizPlace.getCityId());
        //1、验证储值卡的金额是否足够，
        //2、先从储值卡金额扣除，如果不足再从赠送金额扣除，更新储值卡信息
        PlaceMemberCardVo memberCard = reqPlaceTicketInfo.getPlaceMemberCardVo();
        List<ReqPayInfo> payInfos = reqPlaceTicketInfo.getPayInfos();
        Iterator<ReqPayInfo> it = payInfos.iterator();
        while (it.hasNext()) {//删除支付金额为0的支付类型
            ReqPayInfo payInfo = it.next();
            if (PlaceConstants.PAY_WAY_FOR_COUPON.equals(payInfo.getPayId())) {
                payInfo.setSportType(reqPlaceTicketInfo.getCategoryId().byteValue());
                payInfo.setOrderType(CouponOrderType.PLACE.getId().byteValue());
                payInfo.setPlaceId(reqPlaceTicketInfo.getPlaceId());
                payInfo.setCityId(reqPlaceTicketInfo.getCityId());
            }
        }
        /**会员卡和优惠券一起支付**/
        boolean result = false;
        for (ReqPayInfo payInfo : payInfos) {
            if (payInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_COUPON)){
                result = true;
                reqPlaceTicketInfo.setSubjectCode(payInfo.getSubjectCode());
                break;
            }
        }
        reqPlaceTicketInfo.setCouponPay(result);
        if (result){
            //门票加优惠券
            reqPlaceTicketInfo = payTypeHandle(reqPlaceTicketInfo,memberCard, totalPrice);
            totalPrice = reqPlaceTicketInfo.getDisCountAfterAmount();
        }


        logger.info("用户uid:" + uid + "==placeId:" + placeId + "==categoryId:" + categoryId + "==cardNo:" + cardNo + "==库存次数：" + memberCard.getNumbers() + "==提交次数:" + totalCounts + "==订单的总金额：" + totalPrice);
        BigDecimal surplusAmount = memberCard.getSurplusAmount();//账号的剩余金额
        BigDecimal surplusGiveAmount = memberCard.getSurplusGiveAmount();//剩余赠送金额
        try {
            if (null != surplusAmount && surplusAmount.compareTo(totalPrice) > 0) {
                memberCard.setOpBeforeAmount(surplusAmount);//记录消费之前的金额
                memberCard.setSurplusAmount(surplusAmount.subtract(totalPrice));//记录消费之后金额
                memberCard.setOpBeforeNumbers(memberCard.getSurplusNumbers());
                memberCard.setOpBeforeGiveAmount(memberCard.getSurplusGiveAmount());
            } else if (null != surplusGiveAmount && surplusAmount.add(surplusGiveAmount).compareTo(totalPrice) >= 0) {
                if (surplusAmount.compareTo(new BigDecimal(0)) > 0) {
                    memberCard.setOpBeforeAmount(surplusAmount);//记录打折之前的金额
                    memberCard.setSurplusAmount(new BigDecimal(0));
                    memberCard.setOpBeforeGiveAmount(memberCard.getSurplusGiveAmount());
                    memberCard.setSurplusGiveAmount(
                            surplusGiveAmount.subtract(
                                    totalPrice.subtract(surplusAmount).setScale(2, BigDecimal.ROUND_HALF_UP)
                            ).setScale(2, BigDecimal.ROUND_HALF_UP));
                } else {
                    memberCard.setOpBeforeAmount(surplusAmount);//记录打折之前的金额
                    memberCard.setSurplusAmount(new BigDecimal(0));
                    memberCard.setOpBeforeGiveAmount(memberCard.getSurplusGiveAmount());
                    memberCard.setSurplusGiveAmount(surplusGiveAmount.subtract(totalPrice).setScale(2, BigDecimal.ROUND_HALF_UP));
                }
            } else {
                return APIResponse.returnFail(PlaceErrorCodeEnum.BALANCE_NOT_ENOUGH);
            }
            TbBizPlaceMemberCard tbBizPlaceMemberCard = new TbBizPlaceMemberCard();
            BeanUtils.copyProperties(memberCard, tbBizPlaceMemberCard);
            Integer flag = tbBizPlaceMemberCardMapper.updateByPrimaryKeySelective(tbBizPlaceMemberCard);
            if (flag < 0) {
                return APIResponse.returnFail("会员卡记录更新失败");
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.BALANCE_NOT_ENOUGH);
        }
        //封装payInfo;
        for (ReqPayInfo payInfo : payInfos) {
            if (payInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_CARD)){
                if (result){
                    payInfo.setAmount(reqPlaceTicketInfo.getDisCountAfterAmount());
                }else{
                    payInfo.setAmount(totalPrice);
                }
                payInfo.setSubjectCode(cardNo);//会员卡号
            }

        } //门票数
        reqPlaceTicketInfo.setTotalCounts(totalCounts);

        //reqPlaceTicketInfo.setOrderAmount(totalPrice);

        reqPlaceTicketInfo.setOrderAmount(reqPlaceTicketInfo.getPrimePrice());
        //获取订单号
        String orderNo = CommonUtils.generateBusinessOrderNo(Constants.PLACE_SYSTEM, uid);
        reqPlaceTicketInfo.setOrderNo(orderNo);
        //获取流水号
        String no = CommonUtils.generateNo(placeId);
        reqPlaceTicketInfo.setNo(no);
        //历史流水记录
        try {
            Integer historyRecord = inserMerberHistoryRecord(reqPlaceTicketInfo);
            if (historyRecord < 0) {
                throw new BizException(PlaceErrorCodeEnum.TICKET_ERROR);//抛出异常回滚
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.TICKET_ERROR);
        }
        reqPlaceTicketInfo.setVip(true);
        reqPlaceTicketInfo.setIsSendMsg(1);//如果是1则不需要走回调，直接消息推送
        return APIResponse.returnSuccess(respPreOrder(reqPlaceTicketInfo).getData());
    }

    /**
     * 折扣卡支付
     *
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private APIResponse<RespPreOrder> disCountCardOrder(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        Integer placeId = reqPlaceTicketInfo.getPlaceId();
        Integer categoryId = reqPlaceTicketInfo.getCategoryId();
        String cardNo = reqPlaceTicketInfo.getCardNo();
        Integer uid = reqPlaceTicketInfo.getUid();
        //获取门票支付信息
        List<ReqTicketPayInfo> ticketPayInfos = reqPlaceTicketInfo.getTicketPayInfos();
        Integer totalCounts = 0;
        //总价格
        BigDecimal totalPrice = new BigDecimal(0);
        BigDecimal debit = new BigDecimal(0);
        //1、验证储值卡的金额是否足够，
        //2、先从赠送金额扣除，如果不足再从储值卡金额扣除，更新储值卡信息
        PlaceMemberCardVo memberCard = reqPlaceTicketInfo.getPlaceMemberCardVo();
        BigDecimal surplusAmount = memberCard.getSurplusAmount();//存储金额
        //Double disCount = memberCard.getDiscount();//折扣
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
            Integer ticketId = ticketPayInfo.getSalePlanId();
            Integer count = ticketPayInfo.getTicketCount();
            totalCounts += count;
            //客户端传不安全，所以直接从数据库中查询
            TbPlaceTicketSalePlan  placeTicketSalePlan = getTicketSalePlace(ticketId);
            BigDecimal price = placeTicketSalePlan.getMemberPrice();
            //BigDecimal price = ticketPayInfo.getPrice();
            //打折
            /*if (null != disCount && !disCount.equals((double) 100)) {
                tempPrice = price.multiply(new BigDecimal(disCount / (double) 100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                ticketPayInfo.setPrice(tempPrice);//打折后的单价
            } else {
                tempPrice = price.setScale(2, BigDecimal.ROUND_HALF_UP);
            }*/
            BigDecimal tempPrice = price.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP);
            totalPrice = totalPrice.add(tempPrice);

            BigDecimal ticketDebit = placeTicketSalePlan.getPrice();
            debit = debit.add(ticketDebit.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP));
            logger.info("tiackeId:" + ticketId + "====单价：" + price + "====票数" + count + "====总价" + totalPrice);
            //更新门票销售统计
            ticketStatistics(ticketId, placeId, reqPlaceTicketInfo.getChooseDate(), price, count);
        }
        reqPlaceTicketInfo.setPrimePrice(totalPrice);

        reqPlaceTicketInfo.setDebit(debit);


        TbBizPlace tbBizPlace = tbBizPlaceMapper.selectByPrimaryKey(reqPlaceTicketInfo.getPlaceId());
        reqPlaceTicketInfo.setCityId(tbBizPlace.getCityId());
        List<ReqPayInfo> payInfos = reqPlaceTicketInfo.getPayInfos();

        Iterator<ReqPayInfo> it = payInfos.iterator();
        while (it.hasNext()) {//删除支付金额为0的支付类型
            ReqPayInfo payInfo = it.next();
            if (PlaceConstants.PAY_WAY_FOR_COUPON.equals(payInfo.getPayId())) {
                payInfo.setSportType(reqPlaceTicketInfo.getCategoryId().byteValue());
                payInfo.setOrderType(CouponOrderType.PLACE.getId().byteValue());
                payInfo.setPlaceId(reqPlaceTicketInfo.getPlaceId());
                payInfo.setCityId(reqPlaceTicketInfo.getCityId());
            }
        }


        /**会员卡和优惠券一起支付**/
        boolean result = false;
        for (ReqPayInfo payInfo : payInfos) {
            if (payInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_COUPON)){
                result = true;
                reqPlaceTicketInfo.setSubjectCode(payInfo.getSubjectCode());
                break;
            }
        }
        reqPlaceTicketInfo.setCouponPay(result);
        if (result){
            //门票加优惠券
            reqPlaceTicketInfo = payTypeHandle(reqPlaceTicketInfo,memberCard, totalPrice);
            totalPrice = reqPlaceTicketInfo.getDisCountAfterAmount();//记录打折以后价格
        }



        logger.info("用户uid:" + uid + "==placeId:" + placeId + "==categoryId:" + categoryId + "==cardNo:" + cardNo + "==库存次数：" + memberCard.getNumbers() + "==提交次数:" + totalCounts + "==订单的总金额：" + totalPrice);

        try {
            if (null != surplusAmount && surplusAmount.compareTo(totalPrice) >= 0) {
                memberCard.setOpBeforeAmount(memberCard.getSurplusAmount());//记录之前的金额
                memberCard.setSurplusAmount(memberCard.getSurplusAmount().subtract(totalPrice));//记录之后剩余的金额
            } else {
                return APIResponse.returnFail(PlaceErrorCodeEnum.BALANCE_NOT_ENOUGH);
            }
            TbBizPlaceMemberCard tbBizPlaceMemberCard = new TbBizPlaceMemberCard();
            BeanUtils.copyProperties(memberCard, tbBizPlaceMemberCard);
            Integer flag = tbBizPlaceMemberCardMapper.updateByPrimaryKeySelective(tbBizPlaceMemberCard);
            if (flag < 0) {
                return APIResponse.returnFail("会员卡记录更新失败");
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.BALANCE_NOT_ENOUGH);
        }
        //封装payInfo;
       // List<ReqPayInfo> payInfos = reqPlaceTicketInfo.getPayInfos();
        for (ReqPayInfo payInfo : payInfos) {
            if (payInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_CARD)){
                if (result){
                    payInfo.setAmount(reqPlaceTicketInfo.getDisCountAfterAmount());
                }else{
                    payInfo.setAmount(totalPrice);
                }
                payInfo.setSubjectCode(cardNo);//会员卡号
            }
            //payInfo.setAmount(totalPrice);
            //payInfo.setSubjectCode(cardNo);//会员卡号
        } //门票数
        reqPlaceTicketInfo.setTotalCounts(totalCounts);
        //订单总金额
        reqPlaceTicketInfo.setOrderAmount(reqPlaceTicketInfo.getPrimePrice());
        //reqPlaceTicketInfo.setOrderAmount(totalPrice);


        //获取订单号
        String orderNo = CommonUtils.generateBusinessOrderNo(Constants.PLACE_SYSTEM, uid);
        reqPlaceTicketInfo.setOrderNo(orderNo);
        //获取流水号
        String no = CommonUtils.generateNo(placeId);
        reqPlaceTicketInfo.setNo(no);
        //历史流水记录
        try {
            Integer historyRecord = inserMerberHistoryRecord(reqPlaceTicketInfo);
            if (historyRecord < 0) {
                throw new BizException(PlaceErrorCodeEnum.TICKET_ERROR);//抛出异常回滚
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.TICKET_ERROR);
        }
        reqPlaceTicketInfo.setVip(true);
        reqPlaceTicketInfo.setIsSendMsg(1);//如果是1则不需要走回调，直接消息推送
        return APIResponse.returnSuccess(respPreOrder(reqPlaceTicketInfo).getData());
    }

    /**
     * 储值折扣卡支付
     *
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private APIResponse<RespPreOrder> prePayDisCountCardOrder(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        Integer placeId = reqPlaceTicketInfo.getPlaceId();
        Integer categoryId = reqPlaceTicketInfo.getCategoryId();
        String cardNo = reqPlaceTicketInfo.getCardNo();
        Integer uid = reqPlaceTicketInfo.getUid();
        //获取门票支付信息
        List<ReqTicketPayInfo> ticketPayInfos = reqPlaceTicketInfo.getTicketPayInfos();
        Integer totalCounts = 0;
        //总价格
        BigDecimal totalPrice = new BigDecimal(0);

        BigDecimal debit = new BigDecimal(0);
        //1、验证储值卡的金额是否足够，
        //2、先从赠送金额扣除，如果不足再从储值卡金额扣除，更新储值卡信息
        PlaceMemberCardVo memberCard = reqPlaceTicketInfo.getPlaceMemberCardVo();
        BigDecimal surplusAmount = memberCard.getSurplusAmount();//存储金额
        BigDecimal surplusGiveAmount = memberCard.getSurplusGiveAmount();//赠送金额
        //Double disCount = memberCard.getDiscount();//折扣
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
            Integer ticketId = ticketPayInfo.getSalePlanId();
            Integer count = ticketPayInfo.getTicketCount();
            totalCounts += count;
            //客户端传不安全，所以直接从数据库中查询
            TbPlaceTicketSalePlan  placeTicketSalePlan = getTicketSalePlace(ticketId);
            BigDecimal price = placeTicketSalePlan.getMemberPrice();
            //BigDecimal tempPrice = null;
            //打折
          /*  if (null != disCount && !disCount.equals((double) 100)) {
                tempPrice = price.multiply(new BigDecimal(disCount / (double) 100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                ticketPayInfo.setPrice(tempPrice);//打折后的单价
            } else {
                tempPrice = price.setScale(2, BigDecimal.ROUND_HALF_UP);
            }*/
            BigDecimal tempPrice = price.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP);
            totalPrice = totalPrice.add(tempPrice);

            BigDecimal ticketDebit = placeTicketSalePlan.getPrice();
            debit = debit.add(ticketDebit.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP));

            logger.info("tiackeId:" + ticketId + "====单价：" + price + "====票数" + count + "====总价" + totalPrice);
            //更新门票销售统计
            ticketStatistics(ticketId, placeId, reqPlaceTicketInfo.getChooseDate(), price, count);
        }

        logger.info("用户uid:" + uid + "==placeId:" + placeId + "==categoryId:" + categoryId + "==cardNo:" + cardNo + "==库存次数：" + memberCard.getNumbers() + "==提交次数:" + totalCounts + "==订单的总金额：" + totalPrice);
        //门票加优惠券
        reqPlaceTicketInfo.setPrimePrice(totalPrice);
        reqPlaceTicketInfo.setDebit(debit);
        List<ReqPayInfo> payInfos = reqPlaceTicketInfo.getPayInfos();
        TbBizPlace tbBizPlace = tbBizPlaceMapper.selectByPrimaryKey(reqPlaceTicketInfo.getPlaceId());
        reqPlaceTicketInfo.setCityId(tbBizPlace.getCityId());

        Iterator<ReqPayInfo> it = payInfos.iterator();
        while (it.hasNext()) {
            ReqPayInfo payInfo = it.next();
            if (PlaceConstants.PAY_WAY_FOR_COUPON.equals(payInfo.getPayId())) {
                payInfo.setSportType(reqPlaceTicketInfo.getCategoryId().byteValue());
                payInfo.setOrderType(CouponOrderType.PLACE.getId().byteValue());
                payInfo.setPlaceId(reqPlaceTicketInfo.getPlaceId());
                payInfo.setCityId(reqPlaceTicketInfo.getCityId());
            }
        }

        /**会员卡和优惠券一起支付**/
        boolean result = false;
        for (ReqPayInfo payInfo : payInfos) {
            if (payInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_COUPON)){
                result = true;
                reqPlaceTicketInfo.setSubjectCode(payInfo.getSubjectCode());
                break;
            }
        }
        reqPlaceTicketInfo.setCouponPay(result);
        if (result){
            //门票加优惠券
            reqPlaceTicketInfo = payTypeHandle(reqPlaceTicketInfo,memberCard, totalPrice);
            totalPrice = reqPlaceTicketInfo.getDisCountAfterAmount();//记录打折以后价格
        }

        try {
            if (null != surplusAmount && surplusAmount.compareTo(totalPrice) >= 0) {
                memberCard.setOpBeforeAmount(memberCard.getSurplusAmount());//记录打折之前的金额
                memberCard.setSurplusAmount(memberCard.getSurplusAmount().subtract(totalPrice));//记录打折之后剩余的金额
                memberCard.setOpBeforeGiveAmount(memberCard.getSurplusGiveAmount());

            } else if (null != surplusGiveAmount && surplusAmount.add(surplusGiveAmount).compareTo(totalPrice) >= 0) {
                if (surplusAmount.compareTo(new BigDecimal(0)) > 0) {
                    memberCard.setOpBeforeAmount(surplusAmount);//记录打折之前的金额
                    memberCard.setSurplusAmount(new BigDecimal(0));
                    memberCard.setOpBeforeGiveAmount(memberCard.getSurplusGiveAmount());
                    memberCard.setSurplusGiveAmount(
                            surplusGiveAmount.subtract(
                                    totalPrice.subtract(surplusAmount).setScale(2, BigDecimal.ROUND_HALF_UP)
                            ).setScale(2, BigDecimal.ROUND_HALF_UP));
                } else {
                    memberCard.setOpBeforeAmount(surplusAmount);//记录打折之前的金额
                    memberCard.setSurplusAmount(new BigDecimal(0));
                    memberCard.setOpBeforeGiveAmount(memberCard.getSurplusGiveAmount());
                    memberCard.setSurplusGiveAmount(
                            surplusGiveAmount.subtract(totalPrice).setScale(2, BigDecimal.ROUND_HALF_UP));
                }
            } else {
                return APIResponse.returnFail(PlaceErrorCodeEnum.BALANCE_NOT_ENOUGH);
            }
            TbBizPlaceMemberCard tbBizPlaceMemberCard = new TbBizPlaceMemberCard();
            BeanUtils.copyProperties(memberCard, tbBizPlaceMemberCard);
            Integer flag = tbBizPlaceMemberCardMapper.updateByPrimaryKeySelective(tbBizPlaceMemberCard);
            if (flag < 0) {
                return APIResponse.returnFail("会员卡记录更新失败");
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.BALANCE_NOT_ENOUGH);
        }
        //封装payInfo;
       // List<ReqPayInfo> payInfos = reqPlaceTicketInfo.getPayInfos();
        for (ReqPayInfo payInfo : payInfos) {
            if (payInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_CARD)){
                if (result){
                    payInfo.setAmount(reqPlaceTicketInfo.getDisCountAfterAmount());
                }else{
                    payInfo.setAmount(totalPrice);
                }
                payInfo.setSubjectCode(cardNo);//会员卡号
            }
        } //门票数
        reqPlaceTicketInfo.setTotalCounts(totalCounts);
        //订单总金额
        reqPlaceTicketInfo.setOrderAmount(reqPlaceTicketInfo.getPrimePrice());
        //reqPlaceTicketInfo.setOrderAmount(totalPrice);
        //获取订单号
        String orderNo = CommonUtils.generateBusinessOrderNo(Constants.PLACE_SYSTEM, uid);
        reqPlaceTicketInfo.setOrderNo(orderNo);
        //获取流水号
        String no = CommonUtils.generateNo(placeId);
        reqPlaceTicketInfo.setNo(no);
        //历史流水记录
        try {
            Integer historyRecord = inserMerberHistoryRecord(reqPlaceTicketInfo);
            if (historyRecord < 0) {
                throw new BizException(PlaceErrorCodeEnum.TICKET_ERROR);//抛出异常回滚
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.TICKET_ERROR);
        }
        reqPlaceTicketInfo.setVip(true);
        reqPlaceTicketInfo.setIsSendMsg(1);//如果是1则不需要走回调，直接消息推送
        return APIResponse.returnSuccess(respPreOrder(reqPlaceTicketInfo).getData());
    }


    /**
     * 次卡绑定门票支付
     *
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private APIResponse<RespPreOrder> ciCardPreOrder(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        Integer placeId = reqPlaceTicketInfo.getPlaceId();
        Integer categoryId = reqPlaceTicketInfo.getCategoryId();
        String cardNo = reqPlaceTicketInfo.getCardNo();
        Integer uid = reqPlaceTicketInfo.getUid();
        //获取门票支付信息
        List<ReqTicketPayInfo> ticketPayInfos = reqPlaceTicketInfo.getTicketPayInfos();
        //验证门票和会员卡是否被绑定
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
            PlaceMemberCardVo tbBizPlaceMemberCard = reqPlaceTicketInfo.getPlaceMemberCardVo();
            Integer cardTypeId = tbBizPlaceMemberCard.getCardTypeId();//卡类型表id
            TbBizPlaceMemberCardTypeTicket typeTicket = tbBizPlaceMemberCardTypeTicket(cardTypeId, ticketPayInfo.getSalePlanId());
            if (typeTicket == null) {
                return APIResponse.returnFail(PlaceErrorCodeEnum.TICKET_NOT_TIME);
            }
        }
        
        
        /************* add start 次卡价格实收金额修正 by tim 2017/3/14 **/
        Map<String, Object> params = new HashMap<>();
        params.put("memberCardNo",cardNo);
        params.put("placeId",placeId);
        List<TbBizPlaceMemberCardTypeInitAmount> memberCardTypeList = posUnionPayMapper
                .selectCardTypeInitAmoutByPK(params);
        TbBizPlaceMemberCardTypeInitAmount memberCardType = null;
        if (null != memberCardTypeList && memberCardTypeList.size() > 0){
            memberCardType = memberCardTypeList.get(0);
        }
        Integer totalCounts = 0;
        //总价格
        BigDecimal totalPrice = new BigDecimal(0);
        BigDecimal totalPrimePrice=new BigDecimal(0);
        BigDecimal price=new BigDecimal(0);
        BigDecimal primePrice=new BigDecimal(0);
        Long chooseDate = null;
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
           
            Integer ticketId = ticketPayInfo.getSalePlanId();
            Integer count = ticketPayInfo.getTicketCount();
            totalCounts += count;
            chooseDate = reqPlaceTicketInfo.getChooseDate();
            //会员价
            TbPlaceTicketSalePlan  placeTicketSalePlan = getTicketSalePlace(ticketId);
            
             
            if (memberCardType != null) {
            	    price = (memberCardType.getInitAmount()
                         .divide(new BigDecimal(memberCardType.getFrequency()), 2, BigDecimal.ROUND_HALF_UP));// 计算次卡单价
            } else{
            	   price = placeTicketSalePlan.getMemberPrice();
            }
            primePrice=placeTicketSalePlan.getPrice();
            
            BigDecimal tempPrice = price.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP);
            totalPrice = totalPrice.add(tempPrice);
            
            BigDecimal tempPrimePrice=primePrice.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP);
            totalPrimePrice=totalPrimePrice.add(tempPrimePrice);//add by time 增加原价总额
            
            logger.info("tiackeId:" + ticketId + "====单价：" + price + "====票数" + count + "====总价" + totalPrice);
            //更新门票销售统计
            ticketStatistics(ticketId, placeId, chooseDate, price, count);

        }
        //获取用户会员卡库存次数
        PlaceMemberCardVo memberCard = reqPlaceTicketInfo.getPlaceMemberCardVo();
        memberCard.setNumberPrice(price);
        
        Integer surplusNumbers = memberCard.getSurplusNumbers();//获取剩余次数
        logger.info("用户uid:" + uid + "==placeId:" + placeId + "==categoryId:" + categoryId + "==cardNo:" + cardNo + "==库存次数：" + surplusNumbers + "==提交次数:" + totalCounts + "==订单的总金额：" + totalPrice);
        try {
            if (surplusNumbers >= totalCounts) {
                memberCard.setOpBeforeNumbers(surplusNumbers);//记录操作之前次数
                memberCard.setSurplusNumbers(surplusNumbers - totalCounts);//记录操作之后剩余次数
                memberCard.setOpBeforeAmount(memberCard.getSurplusAmount());//修改之前金额就是剩余金额 不做任何修值操作
                memberCard.setOpBeforeGiveAmount(memberCard.getSurplusGiveAmount());//同上
                TbBizPlaceMemberCard tbBizPlaceMemberCard = new TbBizPlaceMemberCard();
                BeanUtils.copyProperties(memberCard, tbBizPlaceMemberCard);
                tbBizPlaceMemberCardMapper.updateByPrimaryKeySelective(tbBizPlaceMemberCard);
            } else {
                //会员卡次数不足
                throw new BizException(PlaceErrorCodeEnum.TICKET_NOT_ENOUGH);//抛出异常回滚
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.TICKET_NOT_ENOUGH);
        }

        //封装payInfo;
        List<ReqPayInfo> payInfos = reqPlaceTicketInfo.getPayInfos();

        for (ReqPayInfo payInfo : payInfos) {
            payInfo.setAmount(totalPrice);
            payInfo.setSubjectCode(cardNo);//会员卡号
        }
        //门票数
        reqPlaceTicketInfo.setTotalCounts(totalCounts);
        //订单总金额
        reqPlaceTicketInfo.setOrderAmount(totalPrice);
        reqPlaceTicketInfo.setDebit(totalPrice);
        //订单原价总金额
        reqPlaceTicketInfo.setPrimePrice(totalPrimePrice);//add by tim 
        //获取订单号
        String orderNo = CommonUtils.generateBusinessOrderNo(Constants.PLACE_SYSTEM, uid);
        reqPlaceTicketInfo.setOrderNo(orderNo);
        //获取流水号
        String no = CommonUtils.generateNo(placeId);
        reqPlaceTicketInfo.setNo(no);
        //历史流水记录
        try {
            Integer historyRecord = inserMerberHistoryRecord(reqPlaceTicketInfo);
            if (historyRecord < 0) {
                throw new BizException(PlaceErrorCodeEnum.TICKET_ERROR);//抛出异常回滚
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.TICKET_ERROR);
        }
        reqPlaceTicketInfo.setVip(true);
        reqPlaceTicketInfo.setIsSendMsg(1);//如果是1则不需要走回调，直接消息推送
        return APIResponse.returnSuccess(respPreOrder(reqPlaceTicketInfo).getData());
    }

    /**
     * 微信支付宝支付
     *
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    @Override
    public APIResponse<RespPreOrder> pay(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        //用户验证
        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer uid = (Integer) httpServletRequest.getAttribute("uid");
        String ver = httpServletRequest.getHeader("APPVersion");
        reqPlaceTicketInfo.setAPPVersion(ver);
        reqPlaceTicketInfo.setUid(uid);
        //下单验证
        APIResponse apiResponse = orderVerification(reqPlaceTicketInfo);
        if( apiResponse != null && !apiResponse.isRet()){
            return apiResponse;
        }

        if (null == reqPlaceTicketInfo.getChooseDate()){
            return APIResponse.returnFail("时间段不能为空");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String tempChooseDate = sdf.format(reqPlaceTicketInfo.getChooseDate());
        try {
            Integer flag = checkTicketDate(reqPlaceTicketInfo);
            if (sdf.parse(tempChooseDate).getTime() == sdf.parse(sdf.format(new Date())).getTime()){
                if (flag.equals(1)){
                    return APIResponse.returnFail("购买的门票时间段不匹配！");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        Integer placeId = reqPlaceTicketInfo.getPlaceId();
        TbBizPlace tbBizPlace = tbBizPlaceMapper.selectByPrimaryKey(placeId);
        reqPlaceTicketInfo.setCityId(tbBizPlace.getCityId());

        Integer categoryId = reqPlaceTicketInfo.getCategoryId();
        boolean isImember = false;
        //判断是否为会员
        if (uid > 0 && placeMemberService.isPlaceMember(uid,
                reqPlaceTicketInfo.getPlaceId(), reqPlaceTicketInfo.getCategoryId(), 0)) {
            isImember = true;
            reqPlaceTicketInfo.setMemberType((byte)1);//TODO
        }


        //获取门票支付信息
        List<ReqTicketPayInfo> ticketPayInfos = reqPlaceTicketInfo.getTicketPayInfos();

        //总价格
        BigDecimal totalPrice = new BigDecimal(0);
        BigDecimal debit = new BigDecimal(0);
        Long chooseDate = null;
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
            Integer ticketId = ticketPayInfo.getSalePlanId();
            Integer count = ticketPayInfo.getTicketCount();
            chooseDate = reqPlaceTicketInfo.getChooseDate();
            //BigDecimal price = ticketPayInfo.getPrice();
            TbPlaceTicketSalePlan  placeTicketSalePlan = getTicketSalePlace(ticketId);
            BigDecimal price = placeTicketSalePlan.getPrice();
            /*if (isImember){
                TbPlaceTicketSalePlan  placeTicketSalePlan = getTicketSalePlace(ticketId);
                 price = placeTicketSalePlan.getMemberPrice();
            }else{
                 price = ticketPayInfo.getPrice();
            }*/
            //price = ticketPayInfo.getPrice();
            BigDecimal tempPrice = price.multiply(new BigDecimal(count)).setScale(2, BigDecimal.ROUND_HALF_UP);
            totalPrice = totalPrice.add(tempPrice);
            debit = debit.add(tempPrice);
            logger.info("tiackeId:" + ticketId + "====单价：" + price + "====票数" + count + "====总价" + totalPrice);
            //更新门票销售统计
            ticketStatistics(ticketId, reqPlaceTicketInfo.getPlaceId(), chooseDate, price, count);
        }
        reqPlaceTicketInfo.setDebit(debit);
        //封装payInfo;
        List<ReqPayInfo> payInfos = reqPlaceTicketInfo.getPayInfos();

        //===start
        //向资产系统获取到用户鸟蛋，H5不需要获取
        BigDecimal eggs = new BigDecimal(0).setScale(0);
        BigDecimal moneyOfEggs = new BigDecimal(0);
        BigDecimal couponDebit = new BigDecimal(0);
        boolean couponUseFlag = false;
        boolean onlyUseCouponPay = false;

        //校验是否使用优惠券
        boolean couponType = false;
        RespCoupon respCoupon = null;
        for (ReqPayInfo payInfo : payInfos) {
            if (PlaceConstants.PAY_WAY_FOR_COUPON.equals(payInfo.getPayId())) {
                reqPlaceTicketInfo.setSubjectCode(payInfo.getSubjectCode());
                APIResponse<RespCoupon> apiCouponResponse = null;
                try {
                    apiCouponResponse = couponService.getInfoByCode(payInfo.getSubjectCode());
                    if (apiCouponResponse.isRet()) {
                        respCoupon = apiCouponResponse.getData();
                        if (null ==  payInfo.getAmount()){
                            couponDebit = respCoupon.getCouponAmount();
                        }else{
                            couponDebit = payInfo.getAmount();
                        }
                        //couponDebit = respCoupon.getCouponAmount();
                       // couponDebit = payInfo.getAmount();
                        couponUseFlag = true;
                        /**判断是折扣券还是抵扣券**/
                        if (respCoupon.getCouponType().equals((byte)2)){
                            couponType = true;
                            couponDebit = payInfo.getAmount();
                        }

                        List<TbPlaceTicketSalePlan> lists = getTbPlaceTicketSalePlan(placeId, reqPlaceTicketInfo.getChooseDate(), categoryId,null);
                        if (null != lists && lists.size()>0){
                            payInfo.setPlaceDateTimeList(ticketLists(lists, reqPlaceTicketInfo.getChooseDate()));
                        }

                    } else {
                        logger.info("获取优惠券信息失败：" + apiCouponResponse.getErrmsg());
                        throw new BizException(PlaceErrorCodeEnum.COUPON_SYSTEM_ERROR);
                    }
                } catch (Exception e) {
                    logger.warn("获取优惠券error：{"+e.getMessage()+"}");
                    throw new BizException(PlaceErrorCodeEnum.COUPON_SYSTEM_ERROR);
                }
            }
        }
        reqPlaceTicketInfo.setCouponPay(couponUseFlag);
        reqPlaceTicketInfo.setRespCoupon(respCoupon);
        //是否只使用优惠券支付
        if (payInfos.size() == 1 && couponUseFlag) {
            onlyUseCouponPay = true;
            reqPlaceTicketInfo.setOnlyUseCouponPay(onlyUseCouponPay);
        }

        //校验是否使用鸟蛋
        for (ReqPayInfo payInfo : payInfos) {
            if (PlaceConstants.PAY_WAY_FOR_AGES.equals(payInfo.getPayId())) {
                com.quanyan.api.APIRequest<ReqRuleDetail> apiRequest = new com.quanyan.api.APIRequest<>();
                ReqRuleDetail reqRuleDetail = new ReqRuleDetail();
                reqRuleDetail.setUid(reqPlaceTicketInfo.getUid());
                reqRuleDetail.setBusinessCode(Constants.PLACE_BOOKING_CODE);
                reqRuleDetail.setSystemCode(Constants.PLACE_SYSTEM_CODE);
                reqRuleDetail.setAssetsType(AssetsType.ASSETS_EGGS.id.byteValue());
                if (couponUseFlag) {
                    reqRuleDetail.setOrderAmount(totalPrice.subtract(couponDebit).setScale(2, BigDecimal.ROUND_HALF_UP));
                } else {
                    reqRuleDetail.setOrderAmount(totalPrice);
                }
                apiRequest.setData(reqRuleDetail);
                APIResponse<List<RespRuleDetail>> respRuleDetailAPIResponse = null;
                try {
                    respRuleDetailAPIResponse = userAssetsService.getUserAccumulateAndRule(apiRequest);
                    if (respRuleDetailAPIResponse == null || !respRuleDetailAPIResponse.isRet()) {
                        throw new BizException(PlaceErrorCodeEnum.ASSETS_SYSTEM_ERROR);
                    }
                } catch (Exception e) {
                    logger.warn("获取鸟蛋error：{"+e.getMessage()+"}");
                    if (respRuleDetailAPIResponse != null && !respRuleDetailAPIResponse.isRet()) {
                        logger.warn("uid：{} ，error：{} ", reqPlaceTicketInfo.getUid(), respRuleDetailAPIResponse.getErrmsg());
                    } else {
                        logger.warn("uid：{} ，error：{} ", reqPlaceTicketInfo.getUid(), e.getMessage());
                    }
                    throw new BizException(PlaceErrorCodeEnum.ASSETS_SYSTEM_ERROR);
                }

                List<RespRuleDetail> respRuleDetailList = respRuleDetailAPIResponse.getData();
                if (CollectionUtils.isNotEmpty(respRuleDetailList)) {
                    RespRuleDetail respRuleDetail = respRuleDetailList.get(0);
                    eggs = new BigDecimal(respRuleDetail.getUseAccumulate()).setScale(0);
                    moneyOfEggs = respRuleDetail.getExchangeRMB();
                }
            }

        }

        Iterator<ReqPayInfo> it = payInfos.iterator();
        totalPrice = totalPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
        while (it.hasNext()) {//删除支付金额为0的支付类型
            ReqPayInfo payInfo = it.next();
            if (PlaceConstants.PAY_WAY_FOR_AGES.equals(payInfo.getPayId())) {
                payInfo.setAmount(eggs);
            } else if (PlaceConstants.PAY_WAY_FOR_COUPON.equals(payInfo.getPayId())) {
                /**为兼容老版本，普通支付及优惠券折扣，当优惠券金额为0，提示升级最新版本**/
                BigDecimal amount = payInfo.getAmount();
                if (null != amount){
                    int r = amount.compareTo(BigDecimal.ZERO);
                    if (r == 0){
                        return APIResponse.returnFail(PlaceErrorCodeEnum.COUPON_DISCOUNT_PAY_ERROR);
                    }
                    if (r != 0){
                        payInfo.setAmount(amount);
                    }
                }else {
                    int  c = couponDebit.compareTo(BigDecimal.ZERO);
                    if (c == 0){
                        return APIResponse.returnFail(PlaceErrorCodeEnum.COUPON_DISCOUNT_PAY_ERROR);
                    }
                    if (c != 0){
                        payInfo.setAmount(couponDebit);
                    }
                }
                payInfo.setSportType(reqPlaceTicketInfo.getCategoryId().byteValue());
                payInfo.setSubjectCode(respCoupon.getCouponCode());
                payInfo.setOrderType(CouponOrderType.PLACE_TICKETS.getId().byteValue());
                payInfo.setPlaceId(reqPlaceTicketInfo.getPlaceId());
                payInfo.setCityId(reqPlaceTicketInfo.getCityId());
            } else {
                if (couponUseFlag) {
                    BigDecimal money = totalPrice.subtract(moneyOfEggs).setScale(2, BigDecimal.ROUND_HALF_UP);
                    BigDecimal temp = money.subtract(couponDebit).setScale(2, BigDecimal.ROUND_HALF_UP);
                    payInfo.setAmount(temp);
                } else {
                    BigDecimal money = totalPrice.subtract(moneyOfEggs).setScale(2, BigDecimal.ROUND_HALF_UP);
                    payInfo.setAmount(money);
                }
            }
            if (payInfo.getAmount().compareTo(new BigDecimal(0)) == 0) {
                it.remove();
            }
        }

        //优惠券无门槛抵扣
        if(payInfos.size() == 1 && PlaceConstants.PAY_WAY_FOR_COUPON.equals(payInfos.get(0).getPayId())){
            if (!couponType) {
                if (couponDebit.compareTo(totalPrice) >= 0) {
                    reqPlaceTicketInfo.setIsSendMsg(1);
                    payInfos.get(0).setAmount(totalPrice);
                    payInfos.get(0).setSportType(reqPlaceTicketInfo.getCategoryId().byteValue());
                    payInfos.get(0).setSubjectCode(respCoupon.getCouponCode());
                    payInfos.get(0).setOrderType(CouponOrderType.PLACE_TICKETS.getId().byteValue());
                    payInfos.get(0).setPlaceId(reqPlaceTicketInfo.getPlaceId());
                    payInfos.get(0).setCityId(reqPlaceTicketInfo.getCityId());
                    logger.info("优惠券支付：" + JSON.toJSONString(payInfos));
                } else {
                    logger.debug("优惠券支付：" + JSON.toJSONString(payInfos));
                    return APIResponse.returnFail("优惠券支付金额不足" + couponDebit);
                }
            }
        }
        logger.info("reqPlaceTicketInfo对象：{}",JSON.toJSONString(reqPlaceTicketInfo));
        //===end
        //订单总金额
        reqPlaceTicketInfo.setOrderAmount(totalPrice);
        reqPlaceTicketInfo.setPrimePrice(totalPrice);

        //获取订单号
        String orderNo = CommonUtils.generateBusinessOrderNo(Constants.PLACE_SYSTEM, uid);
        reqPlaceTicketInfo.setOrderNo(orderNo);
        //获取流水号
        String no = CommonUtils.generateNo(reqPlaceTicketInfo.getPlaceId());
        reqPlaceTicketInfo.setNo(no);
        reqPlaceTicketInfo.setVip(false);
        return APIResponse.returnSuccess(respPreOrder(reqPlaceTicketInfo).getData());
    }

    /**
     * 再次支付
     * @param reqOrderPay
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    public APIResponse<RespPreOrder> ticketOrderPay(ReqOrderPay reqOrderPay) {
        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer userId = (Integer) httpServletRequest.getAttribute("uid");
        String ver = httpServletRequest.getHeader("APPVersion");
        reqOrderPay.setUid(userId);
        /**查询下单信息**/
        TbBizPlaceOrderExample tbBizPlaceOrderExample = new TbBizPlaceOrderExample();
        TbBizPlaceOrderExample.Criteria criteria = tbBizPlaceOrderExample.createCriteria();
        criteria.andPlaceOrderIdEqualTo(reqOrderPay.getOrderNo());
        criteria.andUidEqualTo(reqOrderPay.getUid());
        List<TbBizPlaceOrder> tbBizPlaceOrders = tbBizPlaceOrderMapper.selectByExample(tbBizPlaceOrderExample);
        if (CollectionUtils.isNotEmpty(tbBizPlaceOrders)) {
            TbBizPlace tbBizPlace = tbBizPlaceMapper.selectByPrimaryKey(tbBizPlaceOrders.get(0).getPlaceId());
            TbBizPlaceOrder tbBizPlaceOrder = tbBizPlaceOrders.get(0);
            Date orderDate = tbBizPlaceOrder.getOrderTime();
            long orderTime = orderDate.getTime();
            if (System.currentTimeMillis() - orderTime >= PlaceConstants.ORDER_EXPIRED_TIME) {
                return APIResponse.returnFail("下单时间超过十分钟，您已经不能支付！");
            }
            /**订单状态为待付款**/
            if (PlaceConstants.ORDER_PREPAY_STATUS.equals(tbBizPlaceOrder.getOrderStatus())) {

                RespPlaceUserInfo userInfo = new RespPlaceUserInfo();
                userInfo.setUid(tbBizPlaceOrder.getUid());
                userInfo.setMobile(tbBizPlaceOrder.getMobile());
                userInfo.setNickName(tbBizPlaceOrder.getCustomerName());

                ReqPlaceTicketInfo reqPlaceTicketInfo = new ReqPlaceTicketInfo();
                reqPlaceTicketInfo.setUserInfo(userInfo);
                Map<String,Object> map = new HashMap<>();
                map.put("useType",tbBizPlaceOrder.getUseType());
                map.put("placeOrderId",tbBizPlaceOrder.getPlaceOrderId());

                BigDecimal debit = tbBizPlaceOrderManagerMapper.clientOrderTotalsPrices(map);
                reqPlaceTicketInfo.setOrderAmount(debit);
                //reqPlaceTicketInfo.setOrderAmount(tbBizPlaceOrder.getDebit());
                reqPlaceTicketInfo.setUid(tbBizPlaceOrder.getUid());
                reqPlaceTicketInfo.setOrderNo(reqOrderPay.getOrderNo());
                reqPlaceTicketInfo.setSubjectURL(tbBizPlace.getBizPlaceUrl());
                reqPlaceTicketInfo.setCityId(reqOrderPay.getMchId());
                reqPlaceTicketInfo.setOpenId(reqOrderPay.getOpenId());
                reqPlaceTicketInfo.setAPPVersion(ver);
                reqPlaceTicketInfo.setLarkAppId(reqOrderPay.getLarkAppId());

                TbBizPlaceOrderItemExample tbBizPlaceOrderItemExample = new TbBizPlaceOrderItemExample();
                TbBizPlaceOrderItemExample.Criteria criteria1 = tbBizPlaceOrderItemExample.createCriteria();
                criteria1.andPlaceOrderIdEqualTo(tbBizPlaceOrder.getPlaceOrderId());
                List<TbBizPlaceOrderItem> tbBizPlaceOrderItems = tbBizPlaceOrderItemMapper.selectByExample(tbBizPlaceOrderItemExample);

                List<ReqTicketPayInfo> ticketPayInfos = new ArrayList<>();
                for (TbBizPlaceOrderItem tbBizPlaceOrderItem : tbBizPlaceOrderItems) {
                    ReqTicketPayInfo reqTicketPayInfo = new ReqTicketPayInfo();
                    reqTicketPayInfo.setPrice(tbBizPlaceOrderItem.getSalePrice());
                    reqTicketPayInfo.setTicketCount(tbBizPlaceOrderItem.getTicketCount());
                    reqTicketPayInfo.setSalePlanId(tbBizPlaceOrderItem.getUnitSalePlanId());
                    ticketPayInfos.add(reqTicketPayInfo);
                }

                //TODO 用户使用非虚拟币的支付方式列表，（只能使用一种，不能混合使用，例如不能同时使用支付宝支付和微信支付）
                List<Integer> values = new ArrayList<>();
                values.add(PlaceConstants.PAY_WAY_ALIPAY);
                values.add(PlaceConstants.PAY_WAY_WEICHAT);
                values.add(PlaceConstants.PAY_WAY_WEICHATH5);
                values.add(PlaceConstants.PAY_WAY_UNION_PAY);
                values.add(PlaceConstants.PAY_WAY_APPLE_PAY);
                values.add(PlaceConstants.PAY_WAY_FOR_WEB_ALIPAY);
                values.add(PlaceConstants.PAY_WAY_FOR_WEIXIN_APPLET);
              //  values.add(PlaceConstants.PAY_WAY_FOR_UNION_PO_PAY);//增加pos支付 by tim

                /**获取当前用户使用的支付方式**/
                List<ReqPayInfo> payInfosTemp = reqOrderPay.getPayInfos();
                List<ReqPayInfo> payInfos = new ArrayList<>();
                for (ReqPayInfo reqPayInfo : payInfosTemp) {//查找非鸟蛋支付的payId
                    if (values.contains(reqPayInfo.getPayId())) {
                        payInfos.add(reqPayInfo);
                    }
                }

                /**查询用户之前使用的支付方式**/
                TbBizPlacePayItemExample tbBizPlacePayItemExample = new TbBizPlacePayItemExample();
                TbBizPlacePayItemExample.Criteria tbBizPlacePayItemCriteria = tbBizPlacePayItemExample.createCriteria();
                tbBizPlacePayItemCriteria.andPlaceOrderIdEqualTo(reqOrderPay.getOrderNo());
                List<TbBizPlacePayItem> tbBizPlacePayItemList = tbBizPlacePayItemMapper.selectByExample(tbBizPlacePayItemExample);

                for (TbBizPlacePayItem tbBizPlacePayItem : tbBizPlacePayItemList) {
                    if (values.contains(tbBizPlacePayItem.getPayType())) {
                        for (ReqPayInfo payInfo : payInfos) {
                            if (!tbBizPlacePayItem.getPayType().equals(payInfo.getPayId())) {
                                //说明用户使用的支付方式发生改变，需要更新数据库
                                tbBizPlacePayItem.setPayType(payInfo.getPayId());
                                TbBizPlacePayItem newTbBizPlacePayItem = new TbBizPlacePayItem();
                                newTbBizPlacePayItem.setId(tbBizPlacePayItem.getId());
                                newTbBizPlacePayItem.setPayType(payInfo.getPayId());
                                tbBizPlacePayItemMapper.updateByPrimaryKeySelective(newTbBizPlacePayItem);
                            }
                        }
                    }
                }
                List<ReqPayInfo> payNewInfos = new ArrayList<>();

                List<ReqPayInfo> payInfoList =
                        tbBizPlaceOrderManagerMapper.selectPayTypeGroupByPayTypeAndOrderId(tbBizPlaceOrder.getPlaceOrderId());
                for (ReqPayInfo reqPayInfo : payInfoList) {
                    //优惠券支付需要以下信息
                    if(PlaceConstants.PAY_WAY_FOR_COUPON == reqPayInfo.getPayId()){
                        reqPayInfo.setSubjectCode(reqPayInfo.getSubjectCode());
                    }
                    reqPayInfo.setCityId(tbBizPlace.getCityId());
                    reqPayInfo.setPlaceId(tbBizPlaceOrders.get(0).getPlaceId());
                    reqPayInfo.setOrderType(CouponOrderType.PLACE_TICKETS.getId().byteValue());
                    reqPayInfo.setSportType(tbBizPlaceOrders.get(0).getCategoryId().byteValue());
                    payNewInfos.add(reqPayInfo);
                }
               /* for (TbBizPlacePayItem tbBizPlacePayItem : tbBizPlacePayItemList) {
                    ReqPayInfo reqPayInfo = new ReqPayInfo();
                    reqPayInfo.setAmount(tbBizPlacePayItem.getAmount());
                    reqPayInfo.setPayId(tbBizPlacePayItem.getPayType());
                    //优惠券支付需要以下信息
                    if(PlaceConstants.PAY_WAY_FOR_COUPON.equals(tbBizPlacePayItem.getPayType())){
                        reqPayInfo.setSportType(tbBizPlaceOrders.get(0).getCategoryId().byteValue());
                        reqPayInfo.setSubjectCode(tbBizPlacePayItem.getSubjectCode());
                        reqPayInfo.setOrderType(CouponOrderType.PLACE_TICKETS.getId().byteValue());
                        reqPayInfo.setPlaceId(tbBizPlace.getId());
                    }
                    payNewInfos.add(reqPayInfo);
                }*/
                //优惠券无门槛抵扣,再次支付时，发送推送消息
                if(payNewInfos.size() == 1 && PlaceConstants.PAY_WAY_FOR_COUPON.equals(payNewInfos.get(0).getPayId())){
                    reqPlaceTicketInfo.setIsSendMsg(1);
                }
                reqPlaceTicketInfo.setMchId(reqOrderPay.getMchId());

                reqPlaceTicketInfo.setPayInfos(payNewInfos);
                //设置回调方式
                TbCommonParameter parameter = baseService.getParameterByKey(SysParameterConfigEnum.PLACE_ORDER_CALLBACK_TYPE.getCode());
                Integer callbackType = 0;
                if (parameter != null && parameter.getParameterValue() != null) {
                    callbackType = Integer.valueOf(parameter.getParameterValue());
                }
                reqPlaceTicketInfo.setCallbackType(callbackType);
                if (!org.springframework.util.StringUtils.isEmpty(reqOrderPay.getReturnUrlForH5())){
                    reqPlaceTicketInfo.setReturnUrlForH5(reqOrderPay.getReturnUrlForH5());
                }
                if (!org.springframework.util.StringUtils.isEmpty(reqOrderPay.getShowURLForH5())){
                    reqPlaceTicketInfo.setShowURLForH5(reqOrderPay.getShowURLForH5());
                }
                //调用订单系统，获取预支付信息
                APIResponse<RespPreOrder> respPreOrderAPIResponse = null;
                try {
                    respPreOrderAPIResponse = noticeOrderSystem(reqPlaceTicketInfo, tbBizPlace, ticketPayInfos, false);
                    if (respPreOrderAPIResponse == null || !respPreOrderAPIResponse.isRet()) {
                        throw new BizException(PlaceErrorCodeEnum.ORDER_SYSTEM_ERROR);
                    }else {
                        RespPreOrder respPreOrder = respPreOrderAPIResponse.getData();
                        reqPlaceTicketInfo.setResult(respPreOrder.getResult());
                    }

                } catch (Exception e) {
                    if (respPreOrderAPIResponse != null && !respPreOrderAPIResponse.isRet()) {
                        logger.warn("uid：{} ，error：{} ", reqPlaceTicketInfo.getUid(), respPreOrderAPIResponse.getErrmsg());
                    } else {
                        logger.warn("uid：{} ，error：{} ", reqPlaceTicketInfo.getUid(), e.getMessage());
                    }
                    if (respPreOrderAPIResponse.getErrcode() == 21012){
                        throw new BizException(PlaceErrorCodeEnum.TICKET_PAY_CONFIG_ERROR);
                    }
                    if ("该优惠券不能使用".equals(respPreOrderAPIResponse.getErrmsg())){
                        throw new BizException(PlaceErrorCodeEnum.COUPON_NOT_USE);
                    }
                    throw new BizException(PlaceErrorCodeEnum.ORDER_SYSTEM_ERROR);
                }

                return respPreOrderAPIResponse;

            } else if (PlaceConstants.ORDER_PAYED_STATUS.equals(tbBizPlaceOrders.get(0).getOrderStatus())) {
                return APIResponse.returnFail("该订单已经支付！");
            } else {
                return APIResponse.returnFail("订单支付异常！");
            }
        }

        return APIResponse.returnFail("不存在该订单信息！");
    }


    /**
     * 调用订单系统
     *
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private APIResponse<RespPreOrder> respPreOrder(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        //设置回调方式
        TbCommonParameter parameter = baseService.getParameterByKey(SysParameterConfigEnum.PLACE_ORDER_CALLBACK_TYPE.getCode());
        Integer callbackType = 0;
        if (parameter != null && parameter.getParameterValue() != null) {
            callbackType = Integer.valueOf(parameter.getParameterValue());
        }
        reqPlaceTicketInfo.setCallbackType(callbackType);

        /**设置服务开关
         * ServiceSwitch 0:不支持，1:支持
         * **/
        TbCommonParameter parameter1 = baseService.getParameterByKey(SysParameterConfigEnum.PLACE_CONTAIN_VIP.getCode());
        if (parameter1 != null && parameter1.getParameterValue() != null) {
            reqPlaceTicketInfo.setServiceSwitch(Integer.valueOf(parameter1.getParameterValue()));
        }
        reqPlaceTicketInfo.setUseType(PlaceConstants.ORDER_USE_TICKET);

        //通知订单系统，生成订单，需要抛出异常
        RespPreOrder respPreOrder = null;
        APIResponse<RespPreOrder> respPreOrderAPIResponse = null;
        try {
            TbBizPlace tbBizPlace = tbBizPlaceMapper.selectByPrimaryKey(reqPlaceTicketInfo.getPlaceId());
            respPreOrderAPIResponse = noticeOrderSystem(reqPlaceTicketInfo, tbBizPlace, reqPlaceTicketInfo.getTicketPayInfos(), reqPlaceTicketInfo.isVip());
            //存储订单系统的订单号
            if (respPreOrderAPIResponse != null && respPreOrderAPIResponse.isRet()) {
                respPreOrder = respPreOrderAPIResponse.getData();

                reqPlaceTicketInfo.setResult(respPreOrder.getResult());
                TbBizPlaceOrder tbBizPlaceOrder = getPlaceOrder(reqPlaceTicketInfo);
                tbBizPlaceOrder.setOrderNo(respPreOrder.getOrderNo());
                logger.debug("========================插入订单数据:TbBizPlaceOrder:{}", JSON.toJSONString(tbBizPlaceOrder));
                logger.debug("========================插入订单明细及支付方式:reqPlaceTicketInfo:{}", JSON.toJSONString(reqPlaceTicketInfo));
                //插入订单记录
                tbBizPlaceOrderMapper.insertSelective(tbBizPlaceOrder);

                if (reqPlaceTicketInfo.getServiceSwitch().equals(0)){
                    //插入订单明细
                    inserOrderItems(reqPlaceTicketInfo);
                    //插入订单支付方式
                    insertOrderPayItem(reqPlaceTicketInfo);
                }

                if (reqPlaceTicketInfo.getServiceSwitch().equals(1)){
                	//有优惠卷抵扣，获取优惠卷
                	RespCoupon respCoupon = null; 
                	if (reqPlaceTicketInfo.isCouponPay()) {
                		if (reqPlaceTicketInfo.getRespCoupon() != null) {
                			respCoupon = reqPlaceTicketInfo.getRespCoupon();
						} else {
						    //获取优惠卷
	                        try {
	                       	   APIResponse<RespCoupon>  apiCouponResponse = couponService.getInfoByCode(reqPlaceTicketInfo.getSubjectCode());
	                           if(apiCouponResponse.isRet()){
	                               respCoupon = apiCouponResponse.getData();
	                           }else {
	                               logger.info("获取优惠券信息失败：" + apiCouponResponse.getErrmsg());
	                               throw new BizException(PlaceErrorCodeEnum.COUPON_SYSTEM_ERROR);
	                           }
	                       } catch (Exception e) {
	                           e.printStackTrace();
	                           throw new BizException(PlaceErrorCodeEnum.COUPON_SYSTEM_ERROR);
	                       }
						}
					}
                	
                    /***封装公共拆分订单对象***/
                    OrderItemCostDTO orderItemCostDTO = new OrderItemCostDTO();
                    orderItemCostDTO.setPlaceMemberCardVo(reqPlaceTicketInfo.getPlaceMemberCardVo());
                    orderItemCostDTO.setReqPlaceTicketInfo(reqPlaceTicketInfo);
                    orderItemCostDTO.setPayInfoList(reqPlaceTicketInfo.getPayInfos());
                    orderItemCostDTO.setRespCoupon(respCoupon);
                    orderItemCostDTO.setOrderType(2);

                    /***订单明细**/
                    APIResponse orderItemCostResp = apiPlaceOrderService.setOrderItemCostService(orderItemCostDTO);
                    if (null != orderItemCostResp){
                        APIResponse.returnFail("订单明细异常！");
                    }

                    /***付款明细**/
                    APIResponse payItemResp = apiPlaceOrderService.setOrderPayItemCostService(orderItemCostDTO);
                    if (null != payItemResp) {
                        return APIResponse.returnFail("付款明细执行异常！");
                    }

                    
                    /**1、次卡不参与优惠
                     * 2、储值卡单一支付不参与优惠
                     * 3、普通支付且只有一种支付方式则不参与优惠
                     * **/
//                    if(null != reqPlaceTicketInfo.getCardType()){
//                         if (!PlaceConstants.PLACE_MEMBER_CARD_TYPE_NUMBER.equals(reqPlaceTicketInfo.getCardType())) {
//                             if (reqPlaceTicketInfo.getCardType().equals(PlaceConstants.PLACE_MEMBER_CARD_TYPE_VALUE) &&
//                                     reqPlaceTicketInfo.getPayInfos().size() == 1) {
//
//                             } else {
//                                 /***优惠明细**/
//                                 APIResponse orderDiscountItemCostResp = apiPlaceOrderService.setOrderDiscountItemCostService(orderItemCostDTO);
//                                 if (null != orderDiscountItemCostResp) {
//                                     APIResponse.returnFail("折扣优惠明细执行异常！");
//                                 }
//                             }
//                         }
//                    }else{
                        /**
                         * 普通支付且只有一种支付方式（非优惠卷、鸟蛋支付）则不参与优惠
                         */
                        if (reqPlaceTicketInfo.getPayInfos().size() == 1 && PlaceOrderUtil.getMapPayId().contains(reqPlaceTicketInfo.getPayInfos().get(0).getPayId())){
                            /**不做操作**/
                        }else{
                            APIResponse orderDiscount = apiPlaceOrderService.setOrderDiscountItemCostService(orderItemCostDTO);
                            if (null != orderDiscount) {
                                return APIResponse.returnFail("折扣优惠明细执行异常！");
                            }
                        }
                }
            } else {
                throw new BizException(PlaceErrorCodeEnum.ORDER_SYSTEM_ERROR);
            }
        } catch (Exception e) {
            logger.debug("门票下单支付异常：{}", e.getMessage());
            logger.debug("门票下单支付响应对象respPreOrderAPIResponse：{}",JSON.toJSONString(respPreOrderAPIResponse));
            if (respPreOrderAPIResponse != null && !respPreOrderAPIResponse.isRet()) {
                logger.warn("uid：{} ，error：{} ", reqPlaceTicketInfo.getUid(), respPreOrderAPIResponse.getErrmsg());
            } else {
                logger.warn("uid：{} ，error：{} ", reqPlaceTicketInfo.getUid(), e.getMessage());
            }

            if (respPreOrderAPIResponse.getErrcode() == 21012){
                throw new BizException(PlaceErrorCodeEnum.TICKET_PAY_CONFIG_ERROR);
            }

            if ("该优惠券不能使用".equals(respPreOrderAPIResponse.getErrmsg())){
                throw new BizException(PlaceErrorCodeEnum.COUPON_NOT_USE);
            }
            throw new BizException(PlaceErrorCodeEnum.ORDER_SYSTEM_ERROR);
        }
        //消息推送
        if(reqPlaceTicketInfo.getIsSendMsg().equals(1)){
            orderCompleteTicketOperate(reqPlaceTicketInfo);
        }

        return APIResponse.returnSuccess(respPreOrder);
    }
  
    /**
     * 回调订单系统
     *
     * @param reqPlaceTicketInfo
     * @param tbBizPlace
     * @param ticketPayInfos
     * @param isVip
     * @return
     */
    private APIResponse<RespPreOrder> noticeOrderSystem(ReqPlaceTicketInfo reqPlaceTicketInfo, TbBizPlace tbBizPlace, List<ReqTicketPayInfo> ticketPayInfos, boolean isVip) {
        com.quanyan.api.APIRequest<ReqOrderSave> reqOrderSaveAPIRequest = new com.quanyan.api.APIRequest<>();
        ReqOrderSave reqOrderSave = new ReqOrderSave();
        reqOrderSave.setSourceBusinessId(Constants.PLACE_TICKET_CODE);
        reqOrderSave.setSourceSystemId(Constants.PLACE_SYSTEM_CODE);
        reqOrderSave.setPlatformType(reqPlaceTicketInfo.getPlatformType());//设置平台类型
        if (null != reqPlaceTicketInfo.getUserInfo()){
            reqOrderSave.setContactMobile(reqPlaceTicketInfo.getUserInfo().getMobile());
            reqOrderSave.setContactName(reqPlaceTicketInfo.getUserInfo().getNickName());
            reqOrderSave.setUid(reqPlaceTicketInfo.getUserInfo().getUid());
        }else{
            reqOrderSave.setUid(-1);
        }
        if(reqPlaceTicketInfo.getOpenId() != null){
            reqOrderSave.setBuyerAccount(reqPlaceTicketInfo.getOpenId());
        }
        reqOrderSave.setExtraParam("");
        if (reqPlaceTicketInfo.getCityId() != null && reqPlaceTicketInfo.getCityId().equals(3)) {
            reqOrderSave.setMchId(3); //此处为城市ID，必填
        } else {
            reqOrderSave.setMchId(2); //此处为城市ID，必填
        }
        //微信小程序
        Integer mchId = reqPlaceTicketInfo.getMchId();
        if (null != mchId){
            reqOrderSave.setMchId(mchId);
        }
        //如果回调类型为0，则订单系统使用http方式进行回调；如果回调类型为1，使用mq进行处理
        if (reqPlaceTicketInfo.getCallbackType().equals(Constants.IS_NO)) {
            reqOrderSave.setNotifyURL(payUrl);
            reqOrderSave.setCloseNotifyURL(closeOrderUrl);
            reqOrderSave.setRefundNotifyURL(refundUrl);
            reqOrderSave.setExceptionRefundNotify(exceptionRefundUrl);
            logger.info("订单号：{}，支付使用http回调处理。", reqPlaceTicketInfo.getOrderNo());
        } else {
            logger.info("订单号：{}，支付使用mq消息处理。", reqPlaceTicketInfo.getOrderNo());
        }
        if (isVip) {
            List<ReqPayInfo> requestPayInfo = reqPlaceTicketInfo.getPayInfos();
            if (requestPayInfo.size() == 1 && requestPayInfo.get(0).getPayId().equals(PlaceConstants.PAY_WAY_FOR_CARD)){
                reqOrderSave.setOrderAmount(reqPlaceTicketInfo.getPayInfos().get(0).getAmount());
            }else{
                for (ReqPayInfo reqPayInfo : requestPayInfo) {
                    if (reqPayInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_COUPON) || reqPayInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_CARD)){
                        reqOrderSave.setOrderAmount(reqPlaceTicketInfo.getOrderAmount());
                        break;
                    }
                }
            }
        } else {
            reqOrderSave.setOrderAmount(reqPlaceTicketInfo.getOrderAmount());
        }


        reqOrderSave.setOrderDescribe("预定" + tbBizPlace.getName());
        reqOrderSave.setOrderURL(tbBizPlace.getBizPlaceUrl());
        reqOrderSave.setOutTradeNo(reqPlaceTicketInfo.getOrderNo());
        reqOrderSave.setPayNote("");
        reqOrderSave.setUserClientIp("");
        reqOrderSave.setPayTimeOut(PlaceConstants.PAYTIMEOUT);

        reqOrderSave.setShowURL(reqPlaceTicketInfo.getSubjectURL());
        reqOrderSave.setEggInfo(tbBizPlace.getName() + "订场费");
        reqOrderSave.setEggReceiver("百灵鸟");
        reqOrderSave.setVer(reqPlaceTicketInfo.getVer());//设置版本号
        if (!org.springframework.util.StringUtils.isEmpty(reqPlaceTicketInfo.getReturnUrlForH5())){
            reqOrderSave.setReturnUrlForH5(reqPlaceTicketInfo.getReturnUrlForH5());
        }
       if (!org.springframework.util.StringUtils.isEmpty(reqPlaceTicketInfo.getShowURLForH5())){
           reqOrderSave.setShowURLForH5(reqPlaceTicketInfo.getShowURLForH5());
       }

        if (reqPlaceTicketInfo.getOpenId() != null) {
            reqOrderSave.setBuyerAccount(reqPlaceTicketInfo.getOpenId());
        } else {
            reqOrderSave.setBuyerAccount("");
        }
        reqOrderSave.setService(PlaceConstants.SERVICE_CODE);
        List<ReqProductDetail> reqProductDetailList = new ArrayList<>();
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
            ReqProductDetail reqProductDetail = new ReqProductDetail();
            TbPlaceTicketSalePlan tbPlaceTicketSalePlan = tbPlaceTicketSalePlanMapper.selectByPrimaryKey(ticketPayInfo.getSalePlanId());
            reqProductDetail.setShowURL(tbBizPlace.getBizPlaceUrl());
            if (isVip) {
                reqProductDetail.setPrice(tbPlaceTicketSalePlan.getMemberPrice());
            } else {
                reqProductDetail.setPrice(ticketPayInfo.getPrice());
            }
            reqProductDetail.setProductDesc(tbBizPlace.getName());
            reqProductDetail.setProductId(tbPlaceTicketSalePlan.getSaleNo());
            reqProductDetail.setProductName(DateTimeUtils.timeToStr(tbPlaceTicketSalePlan.getStartTime()) + "-" + DateTimeUtils.timeToStr(tbPlaceTicketSalePlan.getEndTime()) + "时段");
            reqProductDetail.setProductURL(tbBizPlace.getBizPlaceUrl());
            reqProductDetail.setQuantity(1);
            reqProductDetailList.add(reqProductDetail);
        }
        reqOrderSave.setProductDetailList(reqProductDetailList);
        reqOrderSave.setPayInfos(reqPlaceTicketInfo.getPayInfos());
        reqOrderSave.setLarkAppId(reqPlaceTicketInfo.getLarkAppId());
        reqOrderSaveAPIRequest.setData(reqOrderSave);


        APIResponse<RespPreOrder> respPreOrderAPIResponse = orderPayService.submitOrder(reqOrderSaveAPIRequest);
        logger.info("支付数据:reqOrderSave:{}", JSON.toJSONString(reqOrderSave));
        logger.info("调用订单系统：respPreOrderAPIResponse:{}",JSON.toJSONString(respPreOrderAPIResponse.getData()));
        return respPreOrderAPIResponse;
    }




    /**
     * 获取鸟蛋抵扣
     *
     * @param uid
     * @param uid
     * @param
     * @return
     */
    private List<TbUserAssets> getAccumulateRule(Integer uid) {
        com.quanyan.api.APIRequest<ReqUserInfo> apiRequest = new com.quanyan.api.APIRequest<>();
        ReqUserInfo reqRuleDetail = new ReqUserInfo();
        reqRuleDetail.setUid(uid);
        reqRuleDetail.setBusinessCode(Constants.PLACE_TICKET_CODE);//
        reqRuleDetail.setSystemCode(Constants.PLACE_SYSTEM_CODE);
        reqRuleDetail.setAssetsType(AssetsType.ASSETS_EGGS.id.byteValue());
        //reqRuleDetail.setOrderAmount(orderAmount);
        apiRequest.setData(reqRuleDetail);
        APIResponse<List<TbUserAssets>> respRuleDetailAPIResponse = null;
        try {
            respRuleDetailAPIResponse = userAssetsService. getUserAccumulateList(apiRequest);
            //respRuleDetailAPIResponse = userAssetsService.getUserAccumulateAndRule(apiRequest);
        } catch (Exception e) {
            logger.warn("uid：{} ，error：{} ", uid, e.getMessage());
            throw new BizException(PlaceErrorCodeEnum.ASSETS_SYSTEM_ERROR);
        }
        if (respRuleDetailAPIResponse != null) {
            if (!respRuleDetailAPIResponse.isRet()) {
                logger.warn("uid：{} ，error：{} ", uid, respRuleDetailAPIResponse.getErrmsg());
                throw new BizException(PlaceErrorCodeEnum.ASSETS_SYSTEM_ERROR);
            }
            if (null != respRuleDetailAPIResponse.getData()) {
                List<TbUserAssets> respRuleDetailList = respRuleDetailAPIResponse.getData();
                return respRuleDetailList;
              /*  if (com.alibaba.dubbo.common.utils.CollectionUtils.isNotEmpty(respRuleDetailList)) {
                    RespRuleDetail respRuleDetail = respRuleDetailList.get(0);
                    List<RespAccumulateRule> accumulateRuleList = new ArrayList<>();
                    RespAccumulateRule respAccumulateRule = new RespAccumulateRule();
                    respAccumulateRule.setAmount(respRuleDetail.getExchangeRMB());
                    respAccumulateRule.setPayId(PlaceConstants.PAY_WAY_FOR_AGES);
                    respAccumulateRule.setName("鸟蛋抵扣");
                    respAccumulateRule.setDescribe("-￥" + respRuleDetail.getExchangeRMB() + "（消耗" + respRuleDetail.getUseAccumulate() + "鸟蛋）");
                    respAccumulateRule.setAccount(respRuleDetail.getAccount());
                    accumulateRuleList.add(respAccumulateRule);
                    return accumulateRuleList;
                } else {
                    List<RespAccumulateRule> accumulateRuleList = new ArrayList<>();
                    RespAccumulateRule respAccumulateRule = new RespAccumulateRule();
                    respAccumulateRule.setAmount(new BigDecimal(0));
                    respAccumulateRule.setPayId(PlaceConstants.PAY_WAY_FOR_AGES);
                    respAccumulateRule.setName("鸟蛋抵扣");
                    respAccumulateRule.setDescribe("-￥0（消耗0鸟蛋）");
                    return accumulateRuleList;
                }*/
            }
        }
        return null;
    }

    /**
     * 获取优惠券
     *
     * @param userId
     * @param categoryId
     * @param orderAmount
     * @return
     */
    private RespOrderCoupon respOrderCoupon(Integer userId, Integer categoryId, BigDecimal orderAmount,Integer cityId,List<TbPlaceTicketSalePlan> lists,Long chooseDate) {
        //获取优惠券列表
        APIRequest<ReqCoupon> apiReqCouponRequest = new APIRequest<>();
        ReqCoupon reqCoupon = new ReqCoupon();
        reqCoupon.setUid(userId);
        reqCoupon.setSportType(categoryId.byteValue());
        reqCoupon.setOrderType(CouponOrderType.PLACE_TICKETS.getId().byteValue());
        reqCoupon.setEnabledAmount(orderAmount);
        if (null != lists && lists.size()>0){
            reqCoupon.setPlaceDateTimeList(ticketLists(lists,chooseDate));
        }

        if (null != cityId){
            reqCoupon.setCityId(cityId);
        }
        apiReqCouponRequest.setData(reqCoupon);
        APIResponse<RespOrderCoupon> apiCouponResponse = null;
        try {
            logger.info("====" + JSON.toJSONString(apiReqCouponRequest));
            apiCouponResponse = couponService.getOrderCouponList(apiReqCouponRequest);
            if (apiCouponResponse.isRet()) {
                RespOrderCoupon respOrderCoupon = apiCouponResponse.getData();
                return respOrderCoupon;
            } else {
                logger.info("获取优惠券列表失败：" + apiCouponResponse.getErrmsg());
            }
        } catch (Exception e) {
            logger.debug("获取优惠券列表失败：" +e.getMessage());
            e.printStackTrace();
            throw new BizException(PlaceErrorCodeEnum.COUPON_SYSTEM_ERROR);
        }
        return null;
    }

    /**
     * 订单
     *
     * @param orderNo
     * @param uid
     * @return
     */
    private List<TbBizPlaceOrder> getPlaceOrder(String orderNo, Integer uid) {
        TbBizPlaceOrderExample tbBizPlaceOrderExample = new TbBizPlaceOrderExample();
        TbBizPlaceOrderExample.Criteria tbBizPlaceOrderExampleCriteria = tbBizPlaceOrderExample.createCriteria();
        tbBizPlaceOrderExampleCriteria.andPlaceOrderIdEqualTo(orderNo);
        tbBizPlaceOrderExampleCriteria.andUidEqualTo(uid);
        tbBizPlaceOrderExampleCriteria.andIsEffectiveEqualTo((byte) 1);//TODO 是否有效
        List<TbBizPlaceOrder> selectByExample = tbBizPlaceOrderMapper.selectByExample(tbBizPlaceOrderExample);
        return selectByExample != null ? selectByExample : null;
    }

    /**
     * 订单明细
     *
     * @param orderNo
     * @return
     */
    private List<TbBizPlaceOrderItem> getOrderItem(String orderNo) {
        TbBizPlaceOrderItemExample tbBizPlaceOrderItemExample = new TbBizPlaceOrderItemExample();
        TbBizPlaceOrderItemExample.Criteria criteria = tbBizPlaceOrderItemExample.createCriteria();
        criteria.andPlaceOrderIdEqualTo(orderNo);
        List<TbBizPlaceOrderItem> placeOrderItems = tbBizPlaceOrderItemMapper.selectByExample(tbBizPlaceOrderItemExample);
        return placeOrderItems != null ? placeOrderItems : null;
    }

    /**
     * 取消订单
     *
     * @param reqOrderOperate
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    public APIResponse<?> orderCancelOperate(ReqOrderOperate reqOrderOperate) {
        //判断订单状态为付款中状态，销售计划状态为正在预定状态
        List<TbBizPlaceOrder> placeOrderList = getPlaceOrder(reqOrderOperate.getOrderNo(), reqOrderOperate.getUid());

        if (CollectionUtils.isEmpty(placeOrderList)) {
            return APIResponse.returnFail("没有该条订单信息！");
        }
        TbBizPlaceOrder placeOrder = placeOrderList.get(0);
        if (PlaceConstants.ORDER_PREPAY_STATUS.equals(placeOrder.getOrderStatus())) {
            //通知订单系统，订单已经被取消 /*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/**/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
            if (PlaceConstants.YES.equals(reqOrderOperate.getIsCallBackOrder())) {
                logger.info("通知订单系统关闭订单，订单号：{}", reqOrderOperate.getOrderNo());
                APIRequest<ReqOrderCancel> orderCancelAPIRequest = new APIRequest<>();
                ReqOrderCancel reqOrderCancel = new ReqOrderCancel();
                reqOrderCancel.setOrderNo(placeOrder.getOrderNo());
                reqOrderCancel.setOutTradeNo(placeOrder.getPlaceOrderId());
                reqOrderCancel.setUid(reqOrderOperate.getUid());
                reqOrderCancel.setSourceBusinessId(PlaceConstants.PLACE_BUSINESS_CODE);
                reqOrderCancel.setSourceSystemId(Constants.PLACE_SYSTEM);
                reqOrderCancel.setCancelReason(reqOrderOperate.getReason());
                reqOrderCancel.setVer(reqOrderOperate.getVer());
                orderCancelAPIRequest.setData(reqOrderCancel);

                APIResponse<BaseEnum> apiResponseOrderCancel = this.orderPayService.orderCancel(orderCancelAPIRequest);
                if (apiResponseOrderCancel == null || !apiResponseOrderCancel.isRet()) {
                    return APIResponse.returnFail("订单取消失败，请重试！");
                }
            }
            List<TbBizPlaceOrderItem> placeOrderItems = getOrderItem(placeOrder.getPlaceOrderId());
            for (TbBizPlaceOrderItem placeOrderItem : placeOrderItems) {
                Integer ticketId = placeOrderItem.getUnitSalePlanId();
                Integer ticketCount = placeOrderItem.getTicketCount();
                Date consumeTime = placeOrderItem.getConsumeTime();
                Integer placeId = placeOrder.getPlaceId();
                TbPlaceTicketSalePlan placeTicketSalePlan = tbPlaceTicketSalePlanMapper.selectByPrimaryKey(ticketId);
                BigDecimal price = placeTicketSalePlan.getPrice();
                TbPlaceTicketStatistics ticketStatis = getTicketStatistics(ticketId, placeId, consumeTime, price);
                if (ticketStatis != null) {
                    //更新门票库存数
                    ticketStatis.setTotal(ticketStatis.getTotal() - ticketCount);//累计门票张数
                    int flag = tbPlaceTicketStatisticsMapper.updateByPrimaryKeySelective(ticketStatis);
                    if (flag == 1) {
                        logger.debug("========================更新门票统计成功。");
                    } else {
                        logger.debug("========================更新门票统计失败。");
                    }
                }
            }
            //更新订单状态为关闭状态
            TbBizPlaceOrderExample tbBizPlaceOrderExample = new TbBizPlaceOrderExample();
            TbBizPlaceOrderExample.Criteria tbBizPlaceOrderCriteria = tbBizPlaceOrderExample.createCriteria();
            tbBizPlaceOrderCriteria.andPlaceOrderIdEqualTo(reqOrderOperate.getOrderNo());
            TbBizPlaceOrder record = new TbBizPlaceOrder();
            record.setOrderStatus(PlaceConstants.ORDER_CLOSE_STATUS);
            record.setOrderStatusChangeDate(new Date());
            record.setEndTime(new Date());
            tbBizPlaceOrderMapper.updateByExampleSelective(record, tbBizPlaceOrderExample);
            //更改订单支付明细的状态为取消状态
            TbBizPlacePayItem tbBizPlacePayItem = new TbBizPlacePayItem();
            tbBizPlacePayItem.setAmountType(PlaceConstants.CANCEL_TYPE);
            TbBizPlacePayItemExample tbBizPlacePayItemExample = new TbBizPlacePayItemExample();
            TbBizPlacePayItemExample.Criteria tbBizPlacePayItemCriteria = tbBizPlacePayItemExample.createCriteria();
            tbBizPlacePayItemCriteria.andPlaceOrderIdEqualTo(reqOrderOperate.getOrderNo());
            tbBizPlacePayItemMapper.updateByExampleSelective(tbBizPlacePayItem, tbBizPlacePayItemExample);
            return APIResponse.returnSuccess("订单取消成功！");
        } else if (PlaceConstants.ORDER_CLOSE_STATUS.equals(placeOrder.getOrderStatus())) {
            return APIResponse.returnSuccess("订单取消已经受理！");
        } else {
            logger.warn("订单取消异常，订单号：{} 订单当前状态：{}", reqOrderOperate.getOrderNo(), placeOrder.getOrderStatus());
            return APIResponse.returnFail("订单取消异常！");
        }
    }

    /**
     * 插入流水记录
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private Integer inserMerberHistoryRecord(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        PlaceMemberCardVo memberCard = reqPlaceTicketInfo.getPlaceMemberCardVo();
        //生成历史记录
        TbBizPlaceMemberOpHistory tbBizPlaceMemberOpHistory = new TbBizPlaceMemberOpHistory();
        //插入流水记录表
        tbBizPlaceMemberOpHistory.setNo(reqPlaceTicketInfo.getNo());
        tbBizPlaceMemberOpHistory.setOrderNo(reqPlaceTicketInfo.getOrderNo());
        Integer uid = reqPlaceTicketInfo.getUid();
        if (null != uid){
            /**获取用户基本信息**/
            APIResponse<RespUserInfoDetail> userInfoDetail = userServiceFacade.queryUserInfoDetail(uid);
            if (null != userInfoDetail){
                RespUserInfoDetail userInfo= userInfoDetail.getData();
                if (null != userInfo){
                    tbBizPlaceMemberOpHistory.setUid(userInfo.getUid());
                    tbBizPlaceMemberOpHistory.setUserName(userInfo.getNickName());
                    tbBizPlaceMemberOpHistory.setMobile(userInfo.getMobile());
                }
            }
        }else{
            tbBizPlaceMemberOpHistory.setUserName("小程序门票散客支付");
        }


        tbBizPlaceMemberOpHistory.setInnerCardNo(reqPlaceTicketInfo.getCardNo());
        tbBizPlaceMemberOpHistory.setCardTypeName(memberCard.getCardName());
        tbBizPlaceMemberOpHistory.setOpTypeName("APP-" + ibaseService.getCommonDataCache("cagetory" +
                reqPlaceTicketInfo.getCategoryId().toString()) + "门票抵扣");
        tbBizPlaceMemberOpHistory.setOpBeforeNumbers(
                memberCard.getOpBeforeNumbers() != null ? memberCard.getOpBeforeNumbers() : null);//操作之前次数
        tbBizPlaceMemberOpHistory.setOpAfterNumbers(
                memberCard.getSurplusNumbers() != null ? memberCard.getSurplusNumbers() : null);//操作之后的次数
        tbBizPlaceMemberOpHistory.setOpBeforeAmount(
                memberCard.getOpBeforeAmount() != null ? memberCard.getOpBeforeAmount() : null);//修改之前金额
        tbBizPlaceMemberOpHistory.setOpAfterAmount(
                memberCard.getSurplusAmount() != null ? memberCard.getSurplusAmount() : null);//修改之后金额
        tbBizPlaceMemberOpHistory.setOpBeforeGiveAmount(
                memberCard.getOpBeforeGiveAmount() != null ? memberCard.getOpBeforeGiveAmount() : null);//修改之前金额
        tbBizPlaceMemberOpHistory.setOpAfterGiveAmount(
                memberCard.getSurplusGiveAmount() != null ? memberCard.getSurplusGiveAmount() : null);//修改之后金额
        tbBizPlaceMemberOpHistory.setPlaceId(reqPlaceTicketInfo.getPlaceId());

        List<ReqPayInfo> reqPayInfos = reqPlaceTicketInfo.getPayInfos();
        Iterator<ReqPayInfo> iterator = reqPayInfos.iterator();
        while (iterator.hasNext()){
            ReqPayInfo reqPayInfo = iterator.next();
            if (10 == reqPayInfo.getPayId().intValue()){
                tbBizPlaceMemberOpHistory.setAmount(reqPayInfo.getAmount());
                break;
            }
        }

        tbBizPlaceMemberOpHistory.setSrc(PlaceConstants.PLACE_MEMBER_CARD_OP_HISTORY_SRC_CONSUMER);
        tbBizPlaceMemberOpHistory.setMemo("会员卡消费");
        tbBizPlaceMemberOpHistory.setType(PlaceConstants.PLACE_MEMBER_HISTORY_TYPE_CONSUMER);
        tbBizPlaceMemberOpHistory.setCreateUid(reqPlaceTicketInfo.getUid());
        tbBizPlaceMemberOpHistory.setOpCardCount(reqPlaceTicketInfo.getTotalCounts());//本次操作此卡的次数
        tbBizPlaceMemberOpHistory.setPayType(PlaceConstants.PAY_WAY_FOR_CARD);
        tbBizPlaceMemberOpHistory.setPlatform(reqPlaceTicketInfo.getPlatformType());
        /**1:IOS 2:Android3:微信4.普通浏览器6.QQ7:微信小程序**/
        int platformType = reqPlaceTicketInfo.getPlatformType();
        if (platformType == 1 || platformType == 2 || platformType == 3 || platformType == 4 || platformType == 6 || platformType == 7){
            tbBizPlaceMemberOpHistory.setSourceType(PlaceConstants.SOURCE_TYPE_COMMONPAY);
        }
        tbBizPlaceMemberOpHistory.setState(PlaceConstants.PLACE_MEMBER_CARD_OP_HISTORY_YES);
        logger.info("========================插入流水记录数据:tbBizPlaceMemberOpHistory:{}", JSON.toJSONString(tbBizPlaceMemberOpHistory));
        return tbBizPlaceMemberOpHistoryMapper.insert(tbBizPlaceMemberOpHistory);

    }

    /**
     * 插入订单明细
     * @param reqPlaceTicketInfo
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private void inserOrderItems(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        List<ReqTicketPayInfo> ticketPayInfos = reqPlaceTicketInfo.getTicketPayInfos();
       
        //插入订单明细表
        for (ReqTicketPayInfo ticketPayInfo : ticketPayInfos) {
            TbPlaceTicketSalePlan tbPlaceTicketSalePlan = tbPlaceTicketSalePlanMapper.selectByPrimaryKey(ticketPayInfo.getSalePlanId());
            TbBizPlaceOrderItem tbBizPlaceOrderItem = new TbBizPlaceOrderItem();
            tbBizPlaceOrderItem.setPlaceOrderId(reqPlaceTicketInfo.getOrderNo());
            tbBizPlaceOrderItem.setUnitSalePlanId(ticketPayInfo.getSalePlanId());
            /***start update saleprice*********** */

            if (null != reqPlaceTicketInfo.getCardType() && reqPlaceTicketInfo.getCardType().intValue() == 4){
                BigDecimal primePrice=new BigDecimal(0);
                if(reqPlaceTicketInfo.getPrimePrice()!=null) {
                    primePrice = reqPlaceTicketInfo.getPrimePrice().divide(new BigDecimal(ticketPayInfo.getTicketCount()), 2, BigDecimal.ROUND_HALF_UP);
                }
                tbBizPlaceOrderItem.setOriginPrice(primePrice);
                tbBizPlaceOrderItem.setSalePrice(reqPlaceTicketInfo.getOrderAmount());
            }else{
                if (null != reqPlaceTicketInfo.getCardType()){
                    tbBizPlaceOrderItem.setSalePrice(tbPlaceTicketSalePlan.getMemberPrice().multiply(new BigDecimal(ticketPayInfo.getTicketCount())));
                }else{
                    tbBizPlaceOrderItem.setSalePrice(tbPlaceTicketSalePlan.getPrice().multiply(new BigDecimal(ticketPayInfo.getTicketCount())));
                }

            }

            /***end update saleprice by tim*********** */
            
            tbBizPlaceOrderItem.setTicketCount(ticketPayInfo.getTicketCount());//票数
            tbBizPlaceOrderItem.setSaleId(tbPlaceTicketSalePlan.getSaleNo());
            tbBizPlaceOrderItem.setConsumeTime(new Date(reqPlaceTicketInfo.getChooseDate()));//消费时间

            tbBizPlaceOrderItem.setItemUuid(UUIDUtils.createId());
            tbBizPlaceOrderItem.setUseType(reqPlaceTicketInfo.getUseType());
            tbBizPlaceOrderItem.setGoodsId(tbPlaceTicketSalePlan.getId());
            tbBizPlaceOrderItem.setGoodsName(tbPlaceTicketSalePlan.getTicketName());
            tbBizPlaceOrderItem.setSurplusGoodsCount(1);
            tbBizPlaceOrderItem.setTotalGoodsCount(1);
            tbBizPlaceOrderItem.setStartTime(tbPlaceTicketSalePlan.getStartTime());
            tbBizPlaceOrderItem.setEndTime(tbPlaceTicketSalePlan.getEndTime());
            /**订单原价 = 商品原价*数量  **/
            tbBizPlaceOrderItem.setOriginPrice(tbPlaceTicketSalePlan.getPrice());
            tbBizPlaceOrderItem.setMemberPrice(tbPlaceTicketSalePlan.getMemberPrice());


           /* if(PlaceConstants.PLACE_MEMBER_CARD_TYPE_DISCOUNT.equals(reqPlaceTicketInfo.getCardType()) || PlaceConstants.PLACE_MEMBER_CARD_TYPE_VALUE_DISCOUNT.equals(reqPlaceTicketInfo.getCardType())){
                Double temp = new Double(reqPlaceTicketInfo.getPlaceMemberCardVo().getDiscount()) / 100;
                BigDecimal discount = new BigDecimal(temp);
                BigDecimal discountAmount = reqPlaceTicketInfo.getPlaceMemberCardVo().getMemberPrice().multiply(discount).setScale(2,BigDecimal.ROUND_HALF_UP);
                tbBizPlaceOrderItem.setSalePrice(discountAmount);//设置打折后会员价
            }
            else {
                tbBizPlaceOrderItem.setSalePrice(reqPlaceTicketInfo..getPlaceMemberCardVo().getMemberPrice());//设置会员价
            }*/

            logger.debug("========================插入订单详情数据:TbBizPlaceOrder:{}", JSON.toJSONString(tbBizPlaceOrderItem));
            tbBizPlaceOrderItemMapper.insert(tbBizPlaceOrderItem);
        }
    }

    /**
     * 插入订单支付方式
     *
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private Integer insertOrderPayItem(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        List<ReqPayInfo> payInfo = reqPlaceTicketInfo.getPayInfos();
        if (CollectionUtils.isNotEmpty(payInfo)) {
            Integer payWayBoss = Integer.valueOf(PlaceConstants.PLACE_ADMIN_PAY_WAYS_BOSS);
            for (ReqPayInfo reqPayInfo : payInfo) {
                    //插入支付方式
                    TbBizPlacePayItem tbBizPlacePayItem = new TbBizPlacePayItem();
                    tbBizPlacePayItem.setPlaceOrderId(reqPlaceTicketInfo.getOrderNo());
                    tbBizPlacePayItem.setAmount(reqPayInfo.getAmount());//总额
                    tbBizPlacePayItem.setAmountType(PlaceConstants.DEBIT_TYPE);
                    tbBizPlacePayItem.setPayType(reqPayInfo.getPayId());//支付方式
                    if (null != reqPayInfo.getPayId() &&
                            null != reqPlaceTicketInfo.getPlaceMemberCardVo() &&
                            PlaceConstants.PAY_WAY_FOR_CARD.equals(reqPayInfo.getPayId()) &&
                            Constants.BYTE_ONE == reqPlaceTicketInfo.getPlaceMemberCardVo().getIsOldMember()){
                        // 与场馆原老板结算的老会员支付方式做特殊处理
                        tbBizPlacePayItem.setPayType(payWayBoss);
                    }
                    tbBizPlacePayItem.setSubjectCode(reqPayInfo.getSubjectCode());
                    if (reqPayInfo.getPayId().equals(PlaceConstants.PAY_WAY_FOR_CARD)){
                        tbBizPlacePayItem.setSubjectCode(reqPlaceTicketInfo.getPlaceMemberCardVo().getInnerCardNo());
                    }

                    tbBizPlacePayItem.setAdminPayType(PlaceOrderUtil.getAdminPayType(reqPayInfo.getPayId()));
                    logger.debug("========================插入订单支付数据:TbBizPlacePayItem:{}", JSON.toJSONString(tbBizPlacePayItem));
                    tbBizPlacePayItemMapper.insertSelective(tbBizPlacePayItem);

            }

        }
        return null;
    }

    /**
     * 封装场馆订单对象
     *
     * @param reqPlaceTicketInfo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    private TbBizPlaceOrder getPlaceOrder(ReqPlaceTicketInfo reqPlaceTicketInfo) {
        //插入订单
        TbBizPlaceOrder tbBizPlaceOrder = new TbBizPlaceOrder();
        if (OrderStatusEnum.USER_PAY_SUCCESS.getCode().equals(reqPlaceTicketInfo.getResult())){
            tbBizPlaceOrder.setOrderStatus(PlaceConstants.ORDER_PAYED_STATUS);
            tbBizPlaceOrder.setPayStatus(PlaceConstants.PAY_STATUS);
        }else{
            tbBizPlaceOrder.setPayStatus(PlaceConstants.NOT_PAY_STATUS);
            tbBizPlaceOrder.setOrderStatus(PlaceConstants.ORDER_PREPAY_STATUS);
        }
        tbBizPlaceOrder.setPlaceOrderId(reqPlaceTicketInfo.getOrderNo());
        tbBizPlaceOrder.setCategoryId(reqPlaceTicketInfo.getCategoryId());

        Integer uid = reqPlaceTicketInfo.getUid();

        if (null != uid){
            /**获取用户基本信息**/
            APIResponse<RespUserInfoDetail> userInfoDetail = userServiceFacade.queryUserInfoDetail(uid);
            if (null != userInfoDetail){
                RespUserInfoDetail userInfo= userInfoDetail.getData();
                if (null != userInfo){
                    tbBizPlaceOrder.setCustomerName(userInfo.getNickName());
                    tbBizPlaceOrder.setMobile(userInfo.getMobile());
                }
            }
        }else{
            tbBizPlaceOrder.setCustomerName("小程序门票散客支付");
        }

        tbBizPlaceOrder.setDescrible(reqPlaceTicketInfo.getDescribe());
        tbBizPlaceOrder.setPlaceId(reqPlaceTicketInfo.getPlaceId());
        tbBizPlaceOrder.setPaymentTime(new Date());
        /*if (reqPlaceTicketInfo.isCouponPay()) {
            tbBizPlaceOrder.setDebit(reqPlaceTicketInfo.getPrimePrice());
        }else{
            tbBizPlaceOrder.setDebit(reqPlaceTicketInfo.getPrimePrice());//订单总金额 by tim
        }*/



        tbBizPlaceOrder.setDebit(reqPlaceTicketInfo.getDebit());

        tbBizPlaceOrder.setDate(new Date());
        tbBizPlaceOrder.setEndTime(new Date());
        tbBizPlaceOrder.setPlatform(reqPlaceTicketInfo.getPlatformType());
        /**1:IOS 2:Android3:微信4.普通浏览器6.QQ7:微信小程序**/
        int platformType = reqPlaceTicketInfo.getPlatformType().intValue();
        Byte sourceType = PlaceOrderUtil.orderSourceTypeByPlatform(platformType);
        if (null != sourceType){
            tbBizPlaceOrder.setSourceType(sourceType);
        }
        Byte orderChannel = PlaceOrderUtil.orderChannelByPlatform(platformType);
        if (null != orderChannel){
            tbBizPlaceOrder.setOrderChannel(orderChannel);
        }



        tbBizPlaceOrder.setOrderStatusChangeDate(new Date());
        tbBizPlaceOrder.setUseType(reqPlaceTicketInfo.getUseType());
        tbBizPlaceOrder.setIsMember(reqPlaceTicketInfo.getMemberType());
        if (!StringUtils.isEmpty(reqPlaceTicketInfo.getCardNo())){
            tbBizPlaceOrder.setInnerCardNo(reqPlaceTicketInfo.getCardNo());
        }
        //tbBizPlaceOrder.setC
        tbBizPlaceOrder.setUid(reqPlaceTicketInfo.getUid());
        if (reqPlaceTicketInfo.isOnlyUseCouponPay()) {
            tbBizPlaceOrder.setPayStatus(PlaceConstants.PAY_STATUS);
            tbBizPlaceOrder.setOrderStatus(PlaceConstants.ORDER_PAYED_STATUS);
            tbBizPlaceOrder.setPaymentTime(new Date());
        }

        TbBizPlace tbBizPlace = tbBizPlaceMapper.selectByPrimaryKey(reqPlaceTicketInfo.getPlaceId());
        tbBizPlaceOrder.setBusinessMode(tbBizPlace.getBusinessMode());
        return tbBizPlaceOrder;
    }

    /**
     *根据用户一天取消订单数、退订单数等验证用户是否可以下单
     * @param reqPlaceTicketInfo
     * @return
     */

    private APIResponse orderVerification(ReqPlaceTicketInfo reqPlaceTicketInfo){
        TbBizPlaceRuleExample tbBizPlaceRuleExample = new TbBizPlaceRuleExample();
        TbBizPlaceRuleExample.Criteria tbBizPlaceRuleCriteria = tbBizPlaceRuleExample.createCriteria();
        tbBizPlaceRuleCriteria.andPlaceIdEqualTo(reqPlaceTicketInfo.getPlaceId());
        List<TbBizPlaceRule> tbBizPlaceRuleList =  tbBizPlaceRuleMapper.selectByExample(tbBizPlaceRuleExample);
        Map<String,String> placeOrderRuleMap = baseService.getPlaceOrderRule();
        int PLACE_PLAN_MAX_CLOSE = 0;//场馆一天最大取消订场次数
        int PLACE_ALL_ORDER_MAX_TIME = 0;//用户一天可预定最大的时段总数
        int PLACE_PLAN_MAX_PAYING = 0; //用户场地预定的最大未支付订单条数

        PLACE_PLAN_MAX_CLOSE = Integer.parseInt(placeOrderRuleMap.get("MAX_CANCEL_ORDRE_NUM"));//场馆一天最大取消订场次数
        PLACE_PLAN_MAX_PAYING = Integer.parseInt(placeOrderRuleMap.get("MAX_NON_PAYMENT_ORDER_NUM"));//用户场地预定的最大未支付订单条数
        if(CollectionUtils.isEmpty(tbBizPlaceRuleList)){
            PLACE_ALL_ORDER_MAX_TIME = PlaceConstants.PLACE_ALL_ORDER_MAX_TIME;
            logger.info("下单验证规则从默认配置中获取，placeId={}",reqPlaceTicketInfo.getPlaceId());
        }
        else {
            TbBizPlaceRule tbBizPlaceRule = tbBizPlaceRuleList.get(0);
            PLACE_ALL_ORDER_MAX_TIME = tbBizPlaceRule.getAllOrderMaxTime();//用户一天可预定最大的时段总数
        }

        TbBizPlaceOrderExample tbBizPlaceOrderExample = new TbBizPlaceOrderExample();
        TbBizPlaceOrderExample.Criteria tbBizPlaceOrderCriteria = tbBizPlaceOrderExample.createCriteria();
        tbBizPlaceOrderCriteria.andUidEqualTo(reqPlaceTicketInfo.getUid());
        tbBizPlaceOrderCriteria.andOrderStatusChangeDateEqualTo(new Date());
        List<Byte> values = new ArrayList<>();
        values.add(PlaceConstants.ORDER_CLOSE_STATUS);
        values.add(PlaceConstants.ORDER_PREPAY_STATUS);
        tbBizPlaceOrderCriteria.andOrderStatusIn(values);

        int PLACE_PLAN_CLOSE_COUNT = 0;
        int PLACE_PLAN_PAYING_COUNT = 0;


        List<TbBizPlaceOrder> placeOrderList = tbBizPlaceOrderMapper.selectByExample(tbBizPlaceOrderExample);
        if(CollectionUtils.isNotEmpty(placeOrderList)){
            for (TbBizPlaceOrder tbBizPlaceOrder : placeOrderList) {
                if(PlaceConstants.ORDER_PREPAY_STATUS.equals(tbBizPlaceOrder.getOrderStatus())){
                    PLACE_PLAN_PAYING_COUNT++;
                }
                if(PlaceConstants.ORDER_CLOSE_STATUS.equals(tbBizPlaceOrder.getOrderStatus())){
                    PLACE_PLAN_CLOSE_COUNT++;
                }
            }

            //判断用户是否已经取消两次订单
            if (PLACE_PLAN_CLOSE_COUNT >= PLACE_PLAN_MAX_CLOSE) {
                return APIResponse.returnFail("您一天之内已经取消订单"+PLACE_PLAN_MAX_CLOSE+"次，不能再下单，请明天再进行预定！");
            }
            //判断用户是否有两条未完成的订单，如果存在，提示用户支付
            if (PLACE_PLAN_PAYING_COUNT >= PLACE_PLAN_MAX_PAYING) {
                return APIResponse.returnFail("您有" + PLACE_PLAN_MAX_PAYING + "条未完成的订单，请先完成付款！");
            }

        }
        return null;
    }

    /**
     * 检查场馆是否共享会员
     * @param placeId
     * @return
     */
    public boolean checkIsShareVip(Integer placeId) {
        TbBizPlaceAttach placeAttach = placeBaseService.getBizPlaceAttach(placeId);
        if (null != placeAttach &&
                null != placeAttach.getIsVipShare() &&
                Constants.BYTE_ONE == placeAttach.getIsVipShare()){
            return true;
        }
        return false;
    }

    /**
     * 门票调用微信小程序接口生成二维码
     * @param reqQRCode
     * @return
     */
    @Override
    public String ticketQRCodeCreate(ReqQRCode reqQRCode) {
        /**
         * 1、获取token
         *    1>微信接口调用获取token
         *      设置到缓存里面
         *    2>从缓存里面获取
         * 2、获取二维码图片字节
         *    1>调用小程序接口
         *      设置缓存里面
         *    2>从缓存里面获取
         * **/

        /**生成二维码接口**/
        try{
            String postJson = JSONObject.toJSONString(reqQRCode);
            String imageKey = "imageKey_"+postJson;

            String imageValue = (String)placeRedisTemplate.get(imageKey);
            if (!StringUtils.isEmpty(imageValue)){
                return imageValue;
            }else{
                /**获取token**/
                String getTokenURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type" +
                        "=client_credential&appid="+appid +
                        "&secret="+secret;
                String tokenKey = "tokenKey";
                String tokenValue = (String)placeRedisTemplate.get(tokenKey);
                if (StringUtils.isEmpty(tokenValue)){
                    tokenValue = HttpClientUtils.get(getTokenURL);
                    JSONObject obj = JSON.parseObject(tokenValue);
                    tokenValue = obj.getString("access_token");
                    /**设置两个小时过期**/
                    placeRedisTemplate.set(tokenKey,tokenValue, 60*60*2);
                }

                String rqCodeURL = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token="+tokenValue;
                logger.debug("get rqCodeURL------------->"+rqCodeURL);
                byte[] resultURL = HttpClientUtils.sendPost(rqCodeURL, postJson);
                sun.misc.BASE64Encoder decoder = new sun.misc.BASE64Encoder();
                String result = "data:image/jpeg;base64,"+decoder.encode(resultURL);
                //return APIResponse.returnSuccess("data:image/jpeg;base64," +result);
                /**缓存成图片的url**/
                placeRedisTemplate.set(imageKey, result, 60*60*2);
                return result;

            }
        }catch (Exception e){
            logger.error("获取token失败！" + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }




}
